Panagiotis Christopoulos Charitos 10 лет назад
Родитель
Сommit
4c22564fe2

+ 6 - 8
include/anki/collision/Aabb.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_COLLISION_AABB_H
-#define ANKI_COLLISION_AABB_H
+#pragma once
 
 #include "anki/collision/ConvexShape.h"
 #include "anki/math/Vec3.h"
@@ -26,19 +25,19 @@ public:
 	}
 
 	Aabb()
-	:	Base(Type::AABB)
+		: Base(Type::AABB)
 	{}
 
 	Aabb(const Vec4& min, const Vec4& max)
-	:	Base(Type::AABB),
-		m_min(min),
-		m_max(max)
+		: Base(Type::AABB)
+		, m_min(min)
+		, m_max(max)
 	{
 		ANKI_ASSERT(m_min.xyz() < m_max.xyz());
 	}
 
 	Aabb(const Aabb& b)
-	:	Base(Type::AABB)
+		: Base(Type::AABB)
 	{
 		operator=(b);
 	}
@@ -126,4 +125,3 @@ private:
 
 } // end namespace anki
 
-#endif

+ 24 - 7
include/anki/collision/Plane.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_COLLISION_PLANE_H
-#define ANKI_COLLISION_PLANE_H
+#pragma once
 
 #include "anki/collision/CollisionShape.h"
 #include "anki/Math.h"
@@ -27,12 +26,12 @@ public:
 
 	/// Default constructor
 	Plane()
-	:	CollisionShape(Type::PLANE)
+		: CollisionShape(Type::PLANE)
 	{}
 
 	/// Copy constructor
 	Plane(const Plane& b)
-	:	CollisionShape(Type::PLANE)
+		: CollisionShape(Type::PLANE)
 	{
 		operator=(b);
 	}
@@ -42,14 +41,14 @@ public:
 
 	/// @see setFrom3Points
 	Plane(const Vec3& p0, const Vec3& p1, const Vec3& p2)
-	:	CollisionShape(Type::PLANE)
+		: CollisionShape(Type::PLANE)
 	{
 		setFrom3Points(p0, p1, p2);
 	}
 
 	/// @see setFromPlaneEquation
 	Plane(F32 a, F32 b, F32 c, F32 d)
-	:	CollisionShape(Type::PLANE)
+		: CollisionShape(Type::PLANE)
 	{
 		setFromPlaneEquation(a, b, c, d);
 	}
@@ -136,6 +135,25 @@ public:
 		return point - m_normal * test(point);
 	}
 
+	/// Find intersection with a vector.
+	Bool intersectVector(const Vec4& p, Vec4& intersection) const
+	{
+		ANKI_ASSERT(p.w() == 0.0);
+		Vec4 pp = p.getNormalized();
+		F32 dot = pp.dot(m_normal);
+
+		if(!isZero(dot))
+		{
+			F32 s = m_offset / dot;
+			intersection = pp * s;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
 	/// Test a CollisionShape
 	template<typename T>
 	F32 testShape(const T& x) const
@@ -160,4 +178,3 @@ private:
 
 } // end namespace anki
 
-#endif

+ 13 - 4
include/anki/scene/Clusterer.h

@@ -12,7 +12,7 @@
 
 namespace anki {
 
-class FrustumComponent;
+class PerspectiveFrustum;
 
 /// @addtogroup scene
 /// @{
@@ -51,7 +51,8 @@ private:
 class Clusterer
 {
 public:
-	static const U TILE_SIZE = 64;
+	static constexpr U TILE_SIZE = 64;
+	static constexpr F32 NEAR_BIAS = 2.0;
 
 	Clusterer(const GenericMemoryPoolAllocator<U8>& alloc)
 		: m_alloc(alloc)
@@ -68,16 +69,22 @@ public:
 		m_counts[1] = tileCountY;
 	}
 
+	void prepare(
+		const PerspectiveFrustum& fr, const SArray<Vec2>& minMaxTileDepth);
+
 	void initTempTestResults(const GenericMemoryPoolAllocator<U8>& alloc,
 		ClustererTestResult& rez) const;
 
-	void prepare(FrustumComponent* frc, const SArray<Vec2>& minMaxTileDepth);
+	void bin(const CollisionShape& cs, const Aabb& aabb,
+		ClustererTestResult& rez) const;
 
 public:
 	class Cluster
 	{
 	public:
-		Aabb m_box;
+		// Intead of Aabb use minimum size variables
+		Vec3 m_min;
+		Vec3 m_max;
 	};
 
 	GenericMemoryPoolAllocator<U8> m_alloc;
@@ -92,6 +99,8 @@ public:
 	F32 m_fovY = 0.0;
 	F32 m_fovX = 0.0;
 
+	F32 m_calcNearOpt = 0.0;
+
 	Cluster& cluster(U x, U y, U z)
 	{
 		ANKI_ASSERT(x < m_counts[0]);

+ 8 - 6
include/anki/util/Array.h

@@ -32,16 +32,18 @@ public:
 
 	Value m_data[N];
 
-	Reference operator[](const PtrSize n)
+	template<typename Y>
+	Reference operator[](const Y n)
 	{
-		ANKI_ASSERT(n < N);
-		return m_data[n];
+		ANKI_ASSERT(static_cast<U>(n) < N);
+		return m_data[static_cast<U>(n)];
 	}
 
-	ConstReference operator[](const PtrSize n) const
+	template<typename Y>
+	ConstReference operator[](const Y n) const
 	{
-		ANKI_ASSERT(n < N);
-		return m_data[n];
+		ANKI_ASSERT(static_cast<U>(n) < N);
+		return m_data[static_cast<U>(n)];
 	}
 
 	Iterator getBegin()

+ 8 - 0
include/anki/util/Functions.h

@@ -122,6 +122,14 @@ inline Bool isAligned(PtrSize alignment, Type value)
 	return ((PtrSize)value % alignment) == 0;
 }
 
+template<typename T>
+inline void swapValues(T& a, T& b)
+{
+	T tmp = b;
+	b = a;
+	a = tmp;
+}
+
 /// A simple template trick to remove the pointer from one type
 ///
 /// Example:

+ 15 - 19
src/collision/Frustum.cpp

@@ -171,49 +171,45 @@ void PerspectiveFrustum::recalculate()
 
 	sinCos(getPi<F32>() + m_fovX / 2.0, s, c);
 	// right
-	m_planesL[(U)PlaneType::RIGHT] = Plane(Vec4(c, 0.0, s, 0.0), 0.0);
+	m_planesL[PlaneType::RIGHT] = Plane(Vec4(c, 0.0, s, 0.0), 0.0);
 	// left
-	m_planesL[(U)PlaneType::LEFT] = Plane(Vec4(-c, 0.0, s, 0.0), 0.0);
+	m_planesL[PlaneType::LEFT] = Plane(Vec4(-c, 0.0, s, 0.0), 0.0);
 
 	sinCos((getPi<F32>() + m_fovY) * 0.5, s, c);
 	// bottom
-	m_planesL[(U)PlaneType::BOTTOM] = Plane(Vec4(0.0, s, c, 0.0), 0.0);
+	m_planesL[PlaneType::BOTTOM] = Plane(Vec4(0.0, s, c, 0.0), 0.0);
 	// top
-	m_planesL[(U)PlaneType::TOP] = Plane(Vec4(0.0, -s, c, 0.0), 0.0);
+	m_planesL[PlaneType::TOP] = Plane(Vec4(0.0, -s, c, 0.0), 0.0);
 
 	// near
-	m_planesL[(U)PlaneType::NEAR] = Plane(Vec4(0.0, 0.0, -1.0, 0.0), m_near);
+	m_planesL[PlaneType::NEAR] = Plane(Vec4(0.0, 0.0, -1.0, 0.0), m_near);
 	// far
-	m_planesL[(U)PlaneType::FAR] = Plane(Vec4(0.0, 0.0, 1.0, 0.0), -m_far);
+	m_planesL[PlaneType::FAR] = Plane(Vec4(0.0, 0.0, 1.0, 0.0), -m_far);
 
 	// Points
 	//
-	Vec4 eye = Vec4(0.0, 0.0, -m_near, 0.0);
-	for(Vec4& p : m_pointsL)
-	{
-		p = eye;
-	}
 
-	F32 x = m_far / tan((getPi<F32>() - m_fovX) / 2.0);
+	// This came from unprojecting. It works, don't touch it
+	F32 x = m_far * tan(m_fovY / 2.0) * m_fovX / m_fovY;
 	F32 y = tan(m_fovY / 2.0) * m_far;
 	F32 z = -m_far;
 
-	m_pointsL[0] += Vec4(x, y, z - m_near, 0.0); // top right
-	m_pointsL[1] += Vec4(-x, y, z - m_near, 0.0); // top left
-	m_pointsL[2] += Vec4(-x, -y, z - m_near, 0.0); // bot left
-	m_pointsL[3] += Vec4(x, -y, z - m_near, 0.0); // bot right
+	m_pointsL[0] = Vec4(x, y, z, 0.0); // top right
+	m_pointsL[1] = Vec4(-x, y, z, 0.0); // top left
+	m_pointsL[2] = Vec4(-x, -y, z, 0.0); // bot left
+	m_pointsL[3] = Vec4(x, -y, z, 0.0); // bot right
 }
 
 //==============================================================================
 void PerspectiveFrustum::calculateProjectionMatrix(F32 fovX, F32 fovY, F32 near,
 	F32 far, Mat4& proj)
 {
-	ANKI_ASSERT(fovX != 0.0 && fovY != 0.0 && near != 0.0 && far != 0.0);
+	ANKI_ASSERT(fovX > 0.0 && fovY > 0.0 && near > 0.0 && far > 0.0);
 	F32 g = near - far;
 
-	F32 f = 1.0 / tan(fovY * 0.5); // f = cot(m_fovY/2)
+	F32 f = 1.0 / tan(fovY / 2.0); // f = cot(m_fovY/2)
 
-	proj(0, 0) = f * fovY / fovX; // = f/aspectRatio;
+	proj(0, 0) = f * (fovY / fovX); // = f/aspectRatio;
 	proj(0, 1) = 0.0;
 	proj(0, 2) = 0.0;
 	proj(0, 3) = 0.0;

+ 40 - 5
src/renderer/Dbg.cpp

@@ -89,7 +89,7 @@ Error Dbg::run(CommandBufferPtr& cmdb)
 	m_drawer->prepareDraw(cmdb);
 	m_drawer->setViewProjectionMatrix(camFr.getViewProjectionMatrix());
 	m_drawer->setModelMatrix(Mat4::getIdentity());
-	m_drawer->drawGrid();
+	//m_drawer->drawGrid();
 
 	SceneGraph& scene = cam.getSceneGraph();
 
@@ -118,7 +118,7 @@ Error Dbg::run(CommandBufferPtr& cmdb)
 
 	(void)err;
 
-	if(1)
+	if(0)
 	{
 		PhysicsDebugDrawer phyd(m_drawer);
 
@@ -155,13 +155,48 @@ Error Dbg::run(CommandBufferPtr& cmdb)
 
 #if 1
 	{
+		Vec4 origin(0.0);
+
+		PerspectiveFrustum fr;
+		const F32 ang = 55.0;
+		fr.setAll(toRad(ang) * m_r->getAspectRatio(), toRad(ang), 1.0, 250.0);
+		fr.resetTransform(Transform(origin, Mat3x4::getIdentity(), 1.0));
+
 		Clusterer c(getAllocator());
 
-		c.init(2, 2);
-		c.prepare(&camFr, SArray<Vec2>());
+		c.init(m_r->getWidth() / 64, m_r->getHeight() / 64);
+		c.prepare(fr, SArray<Vec2>());
 
 		CollisionDebugDrawer cd(m_drawer);
-		camFr.getFrustum().accept(cd);
+		m_drawer->setColor(Vec4(1.0, 0.0, 0.0, 1.0));
+		fr.accept(cd);
+		/*m_drawer->begin(PrimitiveTopology::LINES);
+		m_drawer->pushBackVertex(Vec3(0.f));
+		m_drawer->pushBackVertex(Vec3(0.f, 0.f, -10.f));
+		m_drawer->end();*/
+
+
+		U k = 0;
+		while(0)
+		{
+			F32 neark = c.calcNear(k);
+			if(neark >= c.m_far)
+			{
+				break;
+			}
+			Plane p;
+			p.setNormal(Vec4(0.0, 0.0, -1.0, 0.0));
+			p.setOffset(neark);
+			p.accept(cd);
+			++k;
+		}
+
+		m_drawer->setColor(Vec4(1.0));
+		for(U i = 0; i < c.m_clusters.getSize(); ++i)
+		{
+			Aabb box(c.m_clusters[i].m_min.xyz0(), c.m_clusters[i].m_max.xyz0());
+			box.accept(cd);
+		}
 	}
 #endif
 

+ 2 - 2
src/renderer/DebugDrawer.cpp

@@ -231,7 +231,7 @@ void DebugDrawer::drawGrid()
 	Vec4 col2(1.0, 0.0, 0.0, 1.0);
 
 	const F32 SPACE = 1.0; // space between lines
-	const U NUM = 57;  // lines number. must be odd
+	const I NUM = 57;  // lines number. must be odd
 
 	const F32 GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
 
@@ -239,7 +239,7 @@ void DebugDrawer::drawGrid()
 
 	begin(PrimitiveTopology::LINES);
 
-	for(U x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
+	for(I x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
 	{
 		setColor(col0);
 

+ 36 - 28
src/scene/Clusterer.cpp

@@ -20,24 +20,15 @@ void Clusterer::initTempTestResults(const GenericMemoryPoolAllocator<U8>& alloc,
 //==============================================================================
 F32 Clusterer::calcNear(U k) const
 {
-	F32 Sy = m_counts[1];
-	F32 theta = m_fovY / 2.0;
-	F32 a = 1.0 + (4.0 * tan(theta)) / Sy;
-	F32 neark = m_near * pow(a, F32(k));
+	F32 neark = m_near * pow(m_calcNearOpt, F32(k));
 	return neark;
 }
 
 //==============================================================================
-void Clusterer::prepare(FrustumComponent* frc,
+void Clusterer::prepare(const PerspectiveFrustum& fr,
 	const SArray<Vec2>& minMaxTileDepth)
 {
-	ANKI_ASSERT(frc);
-
 	// Get some things
-	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 fovY = fr.getFovY();
@@ -54,31 +45,44 @@ void Clusterer::prepare(FrustumComponent* frc,
 	m_near = near;
 	m_far = far;
 
+	{
+		F32 Sy = m_counts[1];
+		F32 theta = m_fovY / 2.0;
+		m_calcNearOpt = 1.0 + (2.0 * tan(theta)) / Sy;
+	}
+
 	// Calc depth
 	U k = 1;
 	while(1)
 	{
-		F32 neark = calcNear(k);
+		F32 neark = calcNear(k++);
 		if(neark >= far)
 		{
 			break;
 		}
-		++k;
 	}
-	m_counts[2] = k + 1;
+	m_counts[2] = k - 1;
 
-	// Alloc clusters
+	// Alloc and init clusters
 	U clusterCount = m_counts[0] * m_counts[1] * m_counts[2];
 	if(clusterCount != m_clusters.getSize())
 	{
 		m_clusters.resize(m_alloc, clusterCount);
 	}
+
+	initClusters();
 }
 
 //==============================================================================
 void Clusterer::initClusters()
 {
-	for(U z = 0; z < U(m_counts[2] - 1); ++z)
+	Mat4 proj;
+	PerspectiveFrustum::calculateProjectionMatrix(m_fovX, m_fovY, m_near, m_far,
+		proj);
+	Mat4 invProj = proj.getInverse();
+
+	// For every claster
+	for(U z = 0; z < m_counts[2]; ++z)
 	{
 		for(U y = 0; y < m_counts[1]; ++y)
 		{
@@ -87,12 +91,10 @@ void Clusterer::initClusters()
 				// Compute projection matrix
 				F32 near = calcNear(z);
 				F32 far = calcNear(z + 1);
-
-				Mat4 proj;
-				PerspectiveFrustum::calculateProjectionMatrix(m_fovX, m_fovY,
-					near, far, proj);
-
-				Mat4 invProj = proj.getInverse();
+				if(far > m_far)
+				{
+					far = m_far;
+				}
 
 				// Project some points
 				Vec2 tileMin, tileMax;
@@ -104,13 +106,19 @@ void Clusterer::initClusters()
 				tileMin = tileMin * 2.0 - 1.0;
 				tileMax = tileMax * 2.0 - 1.0;
 
-				Aabb box;
-				Vec4 a = invProj * Vec4(tileMin, 0.0, 1.0);
-				box.setMin(a.xyz0());
-				a = invProj * Vec4(tileMax, 1.0, 1.0);
-				box.setMax(a.xyz0());
+				Vec4 min = invProj * Vec4(tileMin, 0.0, 1.0);
+				min.w() = 0.0;
+				Plane p(Vec4(0.0, 0.0, -1.0, 0.0), near);
+				p.intersectVector(min, min);
+				min.z() = -far;
+
+				Vec4 max = invProj * Vec4(tileMax, 0.0, 1.0);
+				max.w() = 0.0;
+				p = Plane(Vec4(0.0, 0.0, -1.0, 0.0), near);
+				p.intersectVector(max, max);
 
-				cluster(x, y, z).m_box = box;
+				cluster(x, y, z).m_min = min.xyz();
+				cluster(x, y, z).m_max = max.xyz();
 			}
 		}
 	}

+ 8 - 6
testapp/Main.cpp

@@ -43,7 +43,7 @@ App* app;
 ModelNode* horse;
 PerspectiveCamera* cam;
 
-#define PLAYER 1
+#define PLAYER 0
 #define MOUSE 1
 
 Bool profile = false;
@@ -80,16 +80,18 @@ Error init()
 		toRad(ang), 0.2, 200.0);
 	scene.setActiveCamera(cam);
 
-	cam->getComponent<MoveComponent>().
+	/*cam->getComponent<MoveComponent>().
 		setLocalTransform(Transform(Vec4(0.0),
 		Mat3x4(Euler(toRad(0.0), toRad(180.0), toRad(0.0))),
-		1.0));
+		1.0));*/
 
 #if !PLAYER
-	cam->getComponent<MoveComponent>().
-		setLocalTransform(Transform(Vec4(147.392776, -10.132728, 16.607138, 0.0),
+	/*cam->getComponent<MoveComponent>().
+		setLocalTransform(Transform(
+		//Vec4(147.392776, -10.132728, 16.607138, 0.0),
+		Vec4(0.0),
 		Mat3x4(Euler(toRad(0.0), toRad(90.0), toRad(0.0))),
-		1.0));
+		1.0));*/
 #endif
 
 	// lights