Graphics/CullingList: Improve culling list

- Now supports box culling
- Removed branch
- Removed complex hash combination and replaced it with a much faster algorithm
- It now supports partial visibility
This commit is contained in:
Jérôme Leclercq
2018-08-31 17:26:50 +02:00
parent 56873b92b0
commit 7bb6c84752
4 changed files with 205 additions and 168 deletions

View File

@@ -23,11 +23,13 @@ namespace Nz
{
public:
template<CullTest> class Entry;
class BoxEntry;
class NoTestEntry;
class SphereEntry;
class VolumeEntry;
template<CullTest> friend class Entry;
friend BoxEntry;
friend NoTestEntry;
friend SphereEntry;
friend VolumeEntry;
@@ -43,6 +45,10 @@ namespace Nz
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);
@@ -50,37 +56,24 @@ namespace Nz
CullingList& operator=(const CullingList& renderable) = delete;
CullingList& operator=(CullingList&& renderable) = delete;
// STL API
typename ResultContainer::iterator begin();
typename ResultContainer::const_iterator begin() const;
typename ResultContainer::const_iterator cbegin() const;
typename ResultContainer::const_iterator cend() const;
typename ResultContainer::const_reverse_iterator crbegin() const;
typename ResultContainer::const_reverse_iterator crend() const;
bool empty() const;
typename ResultContainer::iterator end();
typename ResultContainer::const_iterator end() const;
typename ResultContainer::reverse_iterator rbegin();
typename ResultContainer::const_reverse_iterator rbegin() const;
typename ResultContainer::reverse_iterator rend();
typename ResultContainer::const_reverse_iterator rend() const;
typename ResultContainer::size_type size() const;
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;
@@ -104,10 +97,12 @@ namespace Nz
bool forceInvalidation;
};
std::vector<BoxVisibilityEntry> m_boxTestList;
std::vector<NoTestVisibilityEntry> m_noTestList;
std::vector<SphereVisibilityEntry> m_sphereTestList;
std::vector<VolumeVisibilityEntry> m_volumeTestList;
ResultContainer m_results;
ResultContainer m_fullyVisibleResults;
ResultContainer m_partiallyVisibleResults;
};
template<typename T>
@@ -135,6 +130,24 @@ namespace Nz
std::size_t m_index;
CullingList* m_parent;
};
template<typename T>
class CullingList<T>::BoxEntry : public CullingList<T>::template Entry<CullTest::Box>
{
friend CullingList;
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<typename T>
class CullingList<T>::NoTestEntry : public CullingList<T>::template Entry<CullTest::NoTest>