diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 4a3ee80c9..4a32f90e5 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -26,11 +26,15 @@ namespace Ndk inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); + inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; + inline const Nz::BoundingVolumef& GetBoundingVolume() const; + static ComponentIndex componentIndex; private: + inline void InvalidateBoundingVolume(); void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index); inline void InvalidateRenderables(); inline void InvalidateTransformMatrix(); @@ -41,6 +45,7 @@ namespace Ndk void OnDetached() override; void OnNodeInvalidated(const Nz::Node* node); + void UpdateBoundingVolume() const; void UpdateTransformMatrix() const; NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot); @@ -61,7 +66,9 @@ namespace Ndk }; std::vector m_renderables; + mutable Nz::BoundingVolumef m_boundingVolume; mutable Nz::Matrix4f m_transformMatrix; + mutable bool m_boundingVolumeUpdated; mutable bool m_transformMatrixUpdated; }; } diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index b51bf94f7..205eb9462 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -8,7 +8,9 @@ namespace Ndk { inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) : Component(graphicsComponent), + m_boundingVolume(graphicsComponent.m_boundingVolume), m_transformMatrix(graphicsComponent.m_transformMatrix), + m_boundingVolumeUpdated(graphicsComponent.m_boundingVolumeUpdated), m_transformMatrixUpdated(graphicsComponent.m_transformMatrixUpdated) { m_renderables.reserve(graphicsComponent.m_renderables.size()); @@ -39,6 +41,14 @@ namespace Ndk r.data.renderOrder = renderOrder; r.renderable = std::move(renderable); r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1)); + + InvalidateBoundingVolume(); + } + + inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const + { + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); } inline void GraphicsComponent::EnsureTransformMatrixUpdate() const @@ -47,6 +57,18 @@ namespace Ndk UpdateTransformMatrix(); } + inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const + { + EnsureBoundingVolumeUpdate(); + + return m_boundingVolume; + } + + inline void GraphicsComponent::InvalidateBoundingVolume() + { + m_boundingVolumeUpdated = false; + } + inline void GraphicsComponent::InvalidateRenderables() { for (Renderable& r : m_renderables) @@ -55,6 +77,7 @@ namespace Ndk inline void GraphicsComponent::InvalidateTransformMatrix() { + m_boundingVolumeUpdated = false; m_transformMatrixUpdated = false; InvalidateRenderables(); diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 566724350..e345bdb85 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -63,6 +63,18 @@ namespace Ndk InvalidateTransformMatrix(); } + void GraphicsComponent::UpdateBoundingVolume() const + { + EnsureTransformMatrixUpdate(); + + m_boundingVolume.MakeNull(); + for (const Renderable& r : m_renderables) + m_boundingVolume.ExtendTo(r.renderable->GetBoundingVolume()); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; + } + void GraphicsComponent::UpdateTransformMatrix() const { NazaraAssert(m_entity && m_entity->HasComponent(), "GraphicsComponent requires NodeComponent"); diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 60a16c260..6f1f4b804 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -30,6 +30,8 @@ namespace Nz BoundingVolume(const BoundingVolume& volume) = default; ~BoundingVolume() = default; + BoundingVolume& ExtendTo(const BoundingVolume& volume); + bool IsFinite() const; bool IsInfinite() const; bool IsNull() const; diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 03e6476bc..15107e755 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -124,6 +124,52 @@ namespace Nz Set(volume); } + + /*! + * \brief Extends the bounding volume to contain another bounding volume + * \return A reference to the the bounding volume + * + * \param volume Other volume to contain + * + * \remark Extending to a null bounding volume has no effect while extending to a infinite bounding volume will set it as infinite + */ + template + BoundingVolume& BoundingVolume::ExtendTo(const BoundingVolume& volume) + { + switch (extend) + { + case Extend_Finite: + { + switch (volume.extend) + { + case Extend_Finite: + { + // Extend the OBB local box + obb.localBox.ExtendTo(volume.obb.localBox); + break; + } + + case Extend_Infinite: + MakeInfinite(); + break; + + case Extend_Null: + break; + } + break; + } + + case Extend_Infinite: + break; //< We already contain the bounding volume + + case Extend_Null: + Set(volume); + break; + } + + return *this; + } + /*! * \brief Checks whether the volume is finite * \return true if extend is Extend_Finite