Browse Source

Adding the skeleton for the clusterer

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
569fd4c149

+ 4 - 2
include/anki/collision/Frustum.h

@@ -151,7 +151,7 @@ public:
 
 
 	/// Copy
 	/// Copy
 	PerspectiveFrustum(const PerspectiveFrustum& b)
 	PerspectiveFrustum(const PerspectiveFrustum& b)
-	:	PerspectiveFrustum()
+		: PerspectiveFrustum()
 	{
 	{
 		*this = b;
 		*this = b;
 	}
 	}
@@ -163,6 +163,7 @@ public:
 		setAll(fovX, fovY, near, far);
 		setAll(fovX, fovY, near, far);
 	}
 	}
 
 
+	/// Get FOV on X axis.
 	F32 getFovX() const
 	F32 getFovX() const
 	{
 	{
 		return m_fovX;
 		return m_fovX;
@@ -173,6 +174,7 @@ public:
 		m_frustumDirty = true;
 		m_frustumDirty = true;
 	}
 	}
 
 
+	/// Get FOV on Y axis.
 	F32 getFovY() const
 	F32 getFovY() const
 	{
 	{
 		return m_fovY;
 		return m_fovY;
@@ -250,7 +252,7 @@ public:
 
 
 	/// Copy
 	/// Copy
 	OrthographicFrustum(const OrthographicFrustum& b)
 	OrthographicFrustum(const OrthographicFrustum& b)
-	:	OrthographicFrustum()
+		: OrthographicFrustum()
 	{
 	{
 		*this = b;
 		*this = b;
 	}
 	}

+ 96 - 0
include/anki/scene/Clusterer.h

@@ -0,0 +1,96 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include "anki/scene/Common.h"
+#include "anki/Math.h"
+#include "anki/collision/Aabb.h"
+#include "anki/core/Timestamp.h"
+
+namespace anki {
+
+class FrustumComponent;
+
+/// @addtogroup scene
+/// @{
+
+/// The result of the cluster tests.
+class ClustererTestResult
+{
+	friend class Clusterer;
+
+public:
+	ClustererTestResult()
+	{}
+
+	~ClustererTestResult()
+	{
+		m_clusterIds.destroy(m_alloc);
+	}
+
+	DArray<Array<U8, 3>>::ConstIterator getClustersBegin() const
+	{
+		return m_clusterIds.getBegin();
+	}
+
+	DArray<Array<U8, 3>>::ConstIterator getClustersEnd() const
+	{
+		return m_clusterIds.getBegin() + m_count;
+	}
+
+private:
+	DArray<Array<U8, 3>> m_clusterIds;
+	U32 m_count = 0;
+	GenericMemoryPoolAllocator<U8> m_alloc;
+};
+
+/// Collection of clusters for visibility tests.
+class Clusterer
+{
+public:
+	static const U TILE_SIZE = 64;
+
+	Clusterer(const GenericMemoryPoolAllocator<U8>& alloc)
+		: m_alloc(alloc)
+	{}
+
+	~Clusterer()
+	{
+		m_clusters.destroy(m_alloc);
+	}
+
+	void init(U tileCountX, U tileCountY);
+
+	void initTempTestResults(const GenericMemoryPoolAllocator<U8>& alloc,
+		ClustererTestResult& rez) const;
+
+	void prepare(FrustumComponent* frc, const SArray<Vec2>& minMaxTileDepth);
+
+private:
+	class Cluster
+	{
+	public:
+		Aabb m_box;
+	};
+
+	GenericMemoryPoolAllocator<U8> m_alloc;
+
+	Array<U8, 3> m_counts;
+
+	/// [z][y][x]
+	DArray<Cluster> m_clusters;
+
+	FrustumComponent* m_frc = nullptr;
+	Timestamp m_frcTimestamp = 0;
+
+	Cluster& cluster(U x, U y, U z)
+	{
+		return m_clusters[m_counts[0] * (z * m_counts[1] + y) + x];
+	}
+};
+/// @}
+
+} // end namespace anki

+ 9 - 0
src/renderer/Drawer.cpp

@@ -97,6 +97,8 @@ public:
 				}
 				}
 
 
 				uniSet(glvar, &mvp[0], arraySize);
 				uniSet(glvar, &mvp[0], arraySize);
+
+				m_drawer->m_r->getFrameAllocator().deleteArray(mvp, arraySize);
 			}
 			}
 			else
 			else
 			{
 			{
@@ -121,6 +123,8 @@ public:
 				}
 				}
 
 
 				uniSet(glvar, &mv[0], arraySize);
 				uniSet(glvar, &mv[0], arraySize);
+
+				m_drawer->m_r->getFrameAllocator().deleteArray(mv, arraySize);
 			}
 			}
 			break;
 			break;
 		case BuildinMaterialVariableId::VP_MATRIX:
 		case BuildinMaterialVariableId::VP_MATRIX:
@@ -145,6 +149,9 @@ public:
 				}
 				}
 
 
 				uniSet(glvar, &normMats[0], arraySize);
 				uniSet(glvar, &normMats[0], arraySize);
+
+				m_drawer->m_r->getFrameAllocator().deleteArray(
+					normMats, arraySize);
 			}
 			}
 			else
 			else
 			{
 			{
@@ -174,6 +181,8 @@ public:
 				}
 				}
 
 
 				uniSet(glvar, &bmvp[0], arraySize);
 				uniSet(glvar, &bmvp[0], arraySize);
+
+				m_drawer->m_r->getFrameAllocator().deleteArray(bmvp, arraySize);
 			}
 			}
 			break;
 			break;
 		case BuildinMaterialVariableId::MAX_TESS_LEVEL:
 		case BuildinMaterialVariableId::MAX_TESS_LEVEL:

+ 66 - 0
src/scene/Clusterer.cpp

@@ -0,0 +1,66 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "anki/scene/Clusterer.h"
+#include "anki/scene/FrustumComponent.h"
+
+namespace anki {
+
+//==============================================================================
+void Clusterer::initTempTestResults(const GenericMemoryPoolAllocator<U8>& alloc,
+	ClustererTestResult& rez) const
+{
+	rez.m_clusterIds.create(alloc, m_clusters.getSize());
+	rez.m_count = 0;
+	rez.m_alloc = alloc;
+}
+
+//==============================================================================
+void Clusterer::prepare(FrustumComponent* frc,
+	const SArray<Vec2>& minMaxTileDepth)
+{
+	ANKI_ASSERT(frc);
+
+	if(frc == m_frc && m_frc->getTimestamp() == m_frcTimestamp)
+	{
+		// Not dirty, early exit
+		return;
+	}
+
+	m_frc = frc;
+	m_frcTimestamp = m_frc->getTimestamp();
+
+	// Calc depth
+	ANKI_ASSERT(frc->getFrustum().getType() == Frustum::Type::PERSPECTIVE);
+	const PerspectiveFrustum& fr =
+		static_cast<const PerspectiveFrustum&>(frc->getFrustum());
+
+	F32 near = fr.getNear();
+	F32 far = fr.getFar();
+	F32 Sy = m_counts[1];
+	F32 theta = fr.getFovY() / 2.0;
+	F32 opt = 1.0 + (4.0 * tan(theta)) / Sy;
+
+	U k = 1;
+	while(1)
+	{
+		F32 neark = near * pow(opt, F32(k));
+		if(neark >= far)
+		{
+			break;
+		}
+		++k;
+	}
+	m_counts[2] = k;
+
+	// Alloc clusters
+	U clusterCount = m_counts[0] * m_counts[1] * m_counts[2];
+	if(clusterCount != m_clusters.getSize())
+	{
+		m_clusters.resize(m_alloc, clusterCount);
+	}
+}
+
+} // end namespace anki