diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index c177e9104..1821f9319 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/CullingList.hpp b/include/Nazara/Graphics/CullingList.hpp deleted file mode 100644 index 86cc49e25..000000000 --- a/include/Nazara/Graphics/CullingList.hpp +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (C) 2021 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Graphics module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_GRAPHICS_CULLINGLIST_HPP -#define NAZARA_GRAPHICS_CULLINGLIST_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - template - class CullingList - { - public: - template class Entry; - class BoxEntry; - class NoTestEntry; - class SphereEntry; - class VolumeEntry; - - template friend class Entry; - friend BoxEntry; - friend NoTestEntry; - friend SphereEntry; - friend VolumeEntry; - - using ResultContainer = std::vector; - - CullingList() = default; - CullingList(const CullingList& renderable) = delete; - CullingList(CullingList&& renderable) = delete; - ~CullingList(); - - std::size_t Cull(const Frustumf& frustum, bool* forceInvalidation = nullptr); - - std::size_t FillWithAllEntries(bool* forceInvalidation = nullptr); - - const ResultContainer& GetFullyVisibleResults() const; - const ResultContainer& GetPartiallyVisibleResults() const; - - BoxEntry RegisterBoxTest(const T* renderable); - NoTestEntry RegisterNoTest(const T* renderable); - SphereEntry RegisterSphereTest(const T* renderable); - VolumeEntry RegisterVolumeTest(const T* renderable); - - CullingList& operator=(const CullingList& renderable) = delete; - CullingList& operator=(CullingList&& renderable) = delete; - - NazaraSignal(OnCullingListRelease, CullingList* /*cullingList*/); - - private: - inline void NotifyBoxUpdate(std::size_t index, const Boxf& boundingVolume); - inline void NotifyForceInvalidation(CullTest type, std::size_t index); - inline void NotifyMovement(CullTest type, std::size_t index, void* oldPtr, void* newPtr); - inline void NotifyRelease(CullTest type, std::size_t index); - inline void NotifySphereUpdate(std::size_t index, const Spheref& sphere); - inline void NotifyVolumeUpdate(std::size_t index, const BoundingVolumef& boundingVolume); - - struct BoxVisibilityEntry - { - Boxf box; - BoxEntry* entry; - const T* renderable; - bool forceInvalidation; - }; - - struct NoTestVisibilityEntry - { - NoTestEntry* entry; - const T* renderable; - bool forceInvalidation; - }; - - struct SphereVisibilityEntry - { - Spheref sphere; - SphereEntry* entry; - const T* renderable; - bool forceInvalidation; - }; - - struct VolumeVisibilityEntry - { - BoundingVolumef volume; - VolumeEntry* entry; - const T* renderable; - bool forceInvalidation; - }; - - std::vector m_boxTestList; - std::vector m_noTestList; - std::vector m_sphereTestList; - std::vector m_volumeTestList; - ResultContainer m_fullyVisibleResults; - ResultContainer m_partiallyVisibleResults; - }; - - template - template - class CullingList::Entry - { - public: - Entry(); - Entry(const Entry&) = delete; - Entry(Entry&& entry); - ~Entry(); - - void ForceInvalidation(); - - CullingList* GetParent() const; - - void UpdateIndex(std::size_t index); - - Entry& operator=(const Entry&) = delete; - Entry& operator=(Entry&& entry); - - protected: - Entry(CullingList* parent, std::size_t index); - - std::size_t m_index; - CullingList* m_parent; - }; - - template - class CullingList::BoxEntry : public CullingList::template Entry - { - friend CullingList; - - using ParentType = Entry; - - public: - BoxEntry(); - BoxEntry(BoxEntry&&) = default; - ~BoxEntry() = default; - - void UpdateBox(const Boxf& box); - - BoxEntry& operator=(BoxEntry&&) = default; - - private: - BoxEntry(CullingList* parent, std::size_t index); - }; - - template - class CullingList::NoTestEntry : public CullingList::template Entry - { - friend CullingList; - - using ParentType = Entry; - - public: - NoTestEntry(); - NoTestEntry(NoTestEntry&&) = default; - ~NoTestEntry() = default; - - NoTestEntry& operator=(NoTestEntry&&) = default; - - private: - NoTestEntry(CullingList* parent, std::size_t index); - }; - - template - class CullingList::SphereEntry : public CullingList::template Entry - { - friend CullingList; - - using ParentType = Entry; - - public: - SphereEntry(); - SphereEntry(SphereEntry&&) = default; - ~SphereEntry() = default; - - void UpdateSphere(const Spheref& sphere); - - SphereEntry& operator=(SphereEntry&&) = default; - - private: - SphereEntry(CullingList* parent, std::size_t index); - }; - - template - class CullingList::VolumeEntry : public CullingList::template Entry - { - friend CullingList; - - using ParentType = Entry; - - public: - VolumeEntry(); - VolumeEntry(VolumeEntry&&) = default; - ~VolumeEntry() = default; - - void UpdateVolume(const BoundingVolumef& sphere); - - VolumeEntry& operator=(VolumeEntry&&) = default; - - private: - VolumeEntry(CullingList* parent, std::size_t index); - }; -} - -#include - -#endif // NAZARA_GRAPHICS_CULLINGLIST_HPP diff --git a/include/Nazara/Graphics/CullingList.inl b/include/Nazara/Graphics/CullingList.inl deleted file mode 100644 index fd43e684f..000000000 --- a/include/Nazara/Graphics/CullingList.inl +++ /dev/null @@ -1,498 +0,0 @@ -// Copyright (C) 2021 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Graphics module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz -{ - template - CullingList::~CullingList() - { - OnCullingListRelease(this); - } - - template - std::size_t CullingList::Cull(const Frustumf& frustum, bool* forceInvalidation) - { - m_fullyVisibleResults.clear(); - m_partiallyVisibleResults.clear(); - - bool forcedInvalidation = false; - - std::size_t fullyVisibleHash = 5U; - std::size_t partiallyVisibleHash = 5U; - - auto CombineHash = [](std::size_t currentHash, std::size_t newHash) - { - return currentHash * 23 + newHash; - }; - - for (BoxVisibilityEntry& entry : m_boxTestList) - { - switch (frustum.Intersect(entry.box)) - { - case IntersectionSide::Inside: - m_fullyVisibleResults.push_back(entry.renderable); - fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Intersecting: - m_partiallyVisibleResults.push_back(entry.renderable); - partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Outside: - break; - } - } - - for (NoTestVisibilityEntry& entry : m_noTestList) - { - m_fullyVisibleResults.push_back(entry.renderable); - CombineHash(fullyVisibleHash, std::hash()(entry.renderable)); - - if (entry.forceInvalidation) - { - forcedInvalidation = true; - entry.forceInvalidation = false; - } - } - - for (SphereVisibilityEntry& entry : m_sphereTestList) - { - switch (frustum.Intersect(entry.sphere)) - { - case IntersectionSide::Inside: - m_fullyVisibleResults.push_back(entry.renderable); - fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Intersecting: - m_partiallyVisibleResults.push_back(entry.renderable); - partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Outside: - break; - } - } - - for (VolumeVisibilityEntry& entry : m_volumeTestList) - { - switch (frustum.Intersect(entry.volume)) - { - case IntersectionSide::Inside: - m_fullyVisibleResults.push_back(entry.renderable); - fullyVisibleHash = CombineHash(fullyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Intersecting: - m_partiallyVisibleResults.push_back(entry.renderable); - partiallyVisibleHash = CombineHash(partiallyVisibleHash, std::hash()(entry.renderable)); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - break; - - case IntersectionSide::Outside: - break; - } - } - - if (forceInvalidation) - *forceInvalidation = forcedInvalidation; - - return 5 + partiallyVisibleHash * 17 + fullyVisibleHash; - } - - template - std::size_t CullingList::FillWithAllEntries(bool* forceInvalidation) - { - m_fullyVisibleResults.clear(); - m_partiallyVisibleResults.clear(); - - bool forcedInvalidation = false; - - std::size_t visibleHash = 5U; - - auto FillWithList = [&](auto& testList) - { - for (auto& entry : testList) - { - m_fullyVisibleResults.push_back(entry.renderable); - visibleHash = visibleHash * 23 + std::hash()(entry.renderable); - - forcedInvalidation = forcedInvalidation | entry.forceInvalidation; - entry.forceInvalidation = false; - } - }; - - FillWithList(m_boxTestList); - FillWithList(m_noTestList); - FillWithList(m_sphereTestList); - FillWithList(m_volumeTestList); - - if (forceInvalidation) - *forceInvalidation = forcedInvalidation; - - return visibleHash; - } - - template - auto CullingList::GetFullyVisibleResults() const -> const ResultContainer& - { - return m_fullyVisibleResults; - } - - template - auto CullingList::GetPartiallyVisibleResults() const -> const ResultContainer& - { - return m_partiallyVisibleResults; - } - - template - auto CullingList::RegisterBoxTest(const T* renderable) -> BoxEntry - { - BoxEntry newEntry(this, m_boxTestList.size()); - m_boxTestList.emplace_back(BoxVisibilityEntry{ Nz::Boxf(), &newEntry, renderable, false }); //< Address of entry will be updated when moving - - return newEntry; - } - - template - auto CullingList::RegisterNoTest(const T* renderable) -> NoTestEntry - { - NoTestEntry newEntry(this, m_volumeTestList.size()); - m_noTestList.emplace_back(NoTestVisibilityEntry{&newEntry, renderable, false}); //< Address of entry will be updated when moving - - return newEntry; - } - - template - auto CullingList::RegisterSphereTest(const T* renderable) -> SphereEntry - { - SphereEntry newEntry(this, m_sphereTestList.size()); - m_sphereTestList.emplace_back(SphereVisibilityEntry{Nz::Spheref(), &newEntry, renderable, false}); //< Address of entry will be updated when moving - - return newEntry; - } - - template - auto CullingList::RegisterVolumeTest(const T* renderable) -> VolumeEntry - { - VolumeEntry newEntry(this, m_volumeTestList.size()); - m_volumeTestList.emplace_back(VolumeVisibilityEntry{Nz::BoundingVolumef(), &newEntry, renderable, false}); //< Address of entry will be updated when moving - - return newEntry; - } - - template - inline void CullingList::NotifyBoxUpdate(std::size_t index, const Boxf& box) - { - m_boxTestList[index].box = box; - } - - template - void CullingList::NotifyForceInvalidation(CullTest type, std::size_t index) - { - switch (type) - { - case CullTest::Box: - { - m_boxTestList[index].forceInvalidation = true; - break; - } - - case CullTest::NoTest: - { - m_noTestList[index].forceInvalidation = true; - break; - } - - case CullTest::Sphere: - { - m_sphereTestList[index].forceInvalidation = true; - break; - } - - case CullTest::Volume: - { - m_volumeTestList[index].forceInvalidation = true; - break; - } - - default: - NazaraInternalError("Unhandled culltype"); - break; - } - } - - template - void CullingList::NotifyMovement(CullTest type, std::size_t index, void* oldPtr, void* newPtr) - { - NazaraUnused(oldPtr); - - switch (type) - { - case CullTest::Box: - { - BoxVisibilityEntry& entry = m_boxTestList[index]; - NazaraAssert(entry.entry == oldPtr, "Invalid box entry"); - - entry.entry = static_cast(newPtr); - break; - } - - case CullTest::NoTest: - { - NoTestVisibilityEntry& entry = m_noTestList[index]; - NazaraAssert(entry.entry == oldPtr, "Invalid entry"); - - entry.entry = static_cast(newPtr); - break; - } - - case CullTest::Sphere: - { - SphereVisibilityEntry& entry = m_sphereTestList[index]; - NazaraAssert(entry.entry == oldPtr, "Invalid sphere entry"); - - entry.entry = static_cast(newPtr); - break; - } - - case CullTest::Volume: - { - VolumeVisibilityEntry& entry = m_volumeTestList[index]; - NazaraAssert(entry.entry == oldPtr, "Invalid volume entry"); - - entry.entry = static_cast(newPtr); - break; - } - - default: - NazaraInternalError("Unhandled culltype"); - break; - } - } - - template - void CullingList::NotifyRelease(CullTest type, std::size_t index) - { - switch (type) - { - case CullTest::Box: - { - m_boxTestList[index] = std::move(m_boxTestList.back()); - m_boxTestList[index].entry->UpdateIndex(index); - m_boxTestList.pop_back(); - break; - } - - case CullTest::NoTest: - { - m_noTestList[index] = std::move(m_noTestList.back()); - m_noTestList[index].entry->UpdateIndex(index); - m_noTestList.pop_back(); - break; - } - - case CullTest::Sphere: - { - m_sphereTestList[index] = std::move(m_sphereTestList.back()); - m_sphereTestList[index].entry->UpdateIndex(index); - m_sphereTestList.pop_back(); - break; - } - - case CullTest::Volume: - { - m_volumeTestList[index] = std::move(m_volumeTestList.back()); - m_volumeTestList[index].entry->UpdateIndex(index); - m_volumeTestList.pop_back(); - break; - } - - default: - NazaraInternalError("Unhandled culltype"); - break; - } - } - - template - void CullingList::NotifySphereUpdate(std::size_t index, const Spheref& sphere) - { - m_sphereTestList[index].sphere = sphere; - } - - template - void CullingList::NotifyVolumeUpdate(std::size_t index, const BoundingVolumef& boundingVolume) - { - m_volumeTestList[index].volume = boundingVolume; - } - - ////////////////////////////////////////////////////////////////////////// - - template - template - CullingList::Entry::Entry() : - m_parent(nullptr) - { - } - - template - template - CullingList::Entry::Entry(CullingList* parent, std::size_t index) : - m_index(index), - m_parent(parent) - { - } - - template - template - CullingList::Entry::Entry(Entry&& entry) : - m_index(entry.m_index), - m_parent(entry.m_parent) - { - if (m_parent) - m_parent->NotifyMovement(Type, m_index, &entry, this); - - entry.m_parent = nullptr; - } - - template - template - CullingList::Entry::~Entry() - { - if (m_parent) - m_parent->NotifyRelease(Type, m_index); - } - - template - template - void CullingList::Entry::ForceInvalidation() - { - m_parent->NotifyForceInvalidation(Type, m_index); - } - - template - template - CullingList* CullingList::Entry::GetParent() const - { - return m_parent; - } - - template - template - void CullingList::Entry::UpdateIndex(std::size_t index) - { - m_index = index; - } - - template - template - typename CullingList::template Entry& CullingList::Entry::operator=(Entry&& entry) - { - m_index = entry.m_index; - m_parent = entry.m_parent; - if (m_parent) - m_parent->NotifyMovement(Type, m_index, &entry, this); - - entry.m_parent = nullptr; - - return *this; - } - - ////////////////////////////////////////////////////////////////////////// - - template - CullingList::BoxEntry::BoxEntry() : - ParentType() - { - } - - template - CullingList::BoxEntry::BoxEntry(CullingList* parent, std::size_t index) : - ParentType(parent, index) - { - } - - template - void CullingList::BoxEntry::UpdateBox(const Boxf& box) - { - this->m_parent->NotifyBoxUpdate(this->m_index, box); - } - - ////////////////////////////////////////////////////////////////////////// - - template - CullingList::NoTestEntry::NoTestEntry() : - ParentType() - { - } - - template - CullingList::NoTestEntry::NoTestEntry(CullingList* parent, std::size_t index) : - ParentType(parent, index) - { - } - - ////////////////////////////////////////////////////////////////////////// - - template - CullingList::SphereEntry::SphereEntry() : - ParentType() - { - } - - template - CullingList::SphereEntry::SphereEntry(CullingList* parent, std::size_t index) : - ParentType(parent, index) - { - } - - template - void CullingList::SphereEntry::UpdateSphere(const Spheref& sphere) - { - this->m_parent->NotifySphereUpdate(this->m_index, sphere); - } - - ////////////////////////////////////////////////////////////////////////// - - template - CullingList::VolumeEntry::VolumeEntry() : - ParentType() - { - } - - template - CullingList::VolumeEntry::VolumeEntry(CullingList* parent, std::size_t index) : - ParentType(parent, index) - { - } - - template - void CullingList::VolumeEntry::UpdateVolume(const BoundingVolumef& volume) - { - this->m_parent->NotifyVolumeUpdate(this->m_index, volume); - } -} - -#include