Panagiotis Christopoulos Charitos 12 years ago
parent
commit
1717ce05dd

+ 11 - 0
docs/drafts/tiler_optimized.txt

@@ -1,3 +1,14 @@
+=============
+Update planes
+=============
+
+planetrf = 22* 14+
+
+updatealltileplanes = planetrf * (16 + 16 + 256 * 2)
+
+sum = 11968* 7616+
+
+
 
 
 
 
 function create_tiles
 function create_tiles

+ 4 - 4
include/anki/math/Mat4.h

@@ -62,13 +62,13 @@ public:
 
 
 	/// @name Operators with F32
 	/// @name Operators with F32
 	/// @{
 	/// @{
-	Mat4  operator+(const F32 f) const;
+	Mat4 operator+(const F32 f) const;
 	Mat4& operator+=(const F32 f);
 	Mat4& operator+=(const F32 f);
-	Mat4  operator-(const F32 f) const;
+	Mat4 operator-(const F32 f) const;
 	Mat4& operator-=(const F32 f);
 	Mat4& operator-=(const F32 f);
-	Mat4  operator*(const F32 f) const;
+	Mat4 operator*(const F32 f) const;
 	Mat4& operator*=(const F32 f);
 	Mat4& operator*=(const F32 f);
-	Mat4  operator/(const F32 f) const;
+	Mat4 operator/(const F32 f) const;
 	Mat4& operator/=(const F32 f);
 	Mat4& operator/=(const F32 f);
 	/// @}
 	/// @}
 
 

+ 6 - 1
include/anki/math/Vec3.h

@@ -98,16 +98,21 @@ public:
 	Vec3 getTransformed(const Vec3& translate, const Mat3& rotate,
 	Vec3 getTransformed(const Vec3& translate, const Mat3& rotate,
 		F32 scale) const;
 		F32 scale) const;
 	void transform(const Vec3& translate, const Mat3& rotate, F32 scale);
 	void transform(const Vec3& translate, const Mat3& rotate, F32 scale);
+
 	Vec3 getTransformed(const Vec3& translate, const Mat3& rotate) const;
 	Vec3 getTransformed(const Vec3& translate, const Mat3& rotate) const;
 	void transform(const Vec3& translate, const Mat3& rotate);
 	void transform(const Vec3& translate, const Mat3& rotate);
+
 	Vec3 getTransformed(const Vec3& translate, const Quat& rotate,
 	Vec3 getTransformed(const Vec3& translate, const Quat& rotate,
 		F32 scale) const;
 		F32 scale) const;
 	void transform(const Vec3& translate, const Quat& rotate, F32 scale);
 	void transform(const Vec3& translate, const Quat& rotate, F32 scale);
+
 	Vec3 getTransformed(const Vec3& translate, const Quat& rotate) const;
 	Vec3 getTransformed(const Vec3& translate, const Quat& rotate) const;
 	void transform(const Vec3& translate, const Quat& rotate);
 	void transform(const Vec3& translate, const Quat& rotate);
+
 	Vec3 getTransformed(const Mat4& transform) const;  ///< 9 muls, 9 adds
 	Vec3 getTransformed(const Mat4& transform) const;  ///< 9 muls, 9 adds
 	void transform(const Mat4& transform);
 	void transform(const Mat4& transform);
-	Vec3 getTransformed(const Transform& transform) const;
+
+	Vec3 getTransformed(const Transform& transform) const; ///< 12 muls, 9 adds
 	void transform(const Transform& transform);
 	void transform(const Transform& transform);
 	/// @}
 	/// @}
 
 

+ 16 - 0
include/anki/renderer/Tiler.h

@@ -20,6 +20,7 @@ class Frustumable;
 class Tiler
 class Tiler
 {
 {
 	friend struct UpdateTilesPlanesPerspectiveCameraJob;
 	friend struct UpdateTilesPlanesPerspectiveCameraJob;
+	friend struct UpdatePlanesPerspectiveCameraJob;
 
 
 public:
 public:
 	// Config. These values affect the size of the uniform blocks and keep in
 	// Config. These values affect the size of the uniform blocks and keep in
@@ -60,6 +61,12 @@ public:
 		Bool nearPlane,
 		Bool nearPlane,
 		Bitset* mask) const;
 		Bitset* mask) const;
 
 
+	Bool test2(
+		const CollisionShape& cs,
+		const Aabb& aabb,
+		Bool nearPlane,
+		Bitset* mask) const;
+
 private:
 private:
 	/// A screen tile
 	/// A screen tile
 	struct Tile
 	struct Tile
@@ -80,6 +87,15 @@ private:
 		Array<I16, 4> children; ///< Use small index to save memory
 		Array<I16, 4> children; ///< Use small index to save memory
 	};
 	};
 
 
+	Vector<Plane> allPlanes;
+	Plane* planesI = nullptr;
+	Plane* planesJ = nullptr;
+	Plane* nearFarPlanes = nullptr;
+	Plane* planesW = nullptr;
+	Plane* planesIW = nullptr;
+	Plane* planesJW = nullptr;
+	Plane* nearFarPlanesW = nullptr;
+
 	typedef F32 PixelArray[TILES_Y_COUNT][TILES_X_COUNT][2];
 	typedef F32 PixelArray[TILES_Y_COUNT][TILES_X_COUNT][2];
 
 
 	/// @note The [0][0] is the bottom left tile
 	/// @note The [0][0] is the bottom left tile

+ 2 - 2
src/collision/Aabb.cpp

@@ -14,8 +14,8 @@ Aabb Aabb::getTransformed(const Transform& transform) const
 		absM[i] = fabs(transform.getRotation()[i]);
 		absM[i] = fabs(transform.getRotation()[i]);
 	}
 	}
 
 
-	Vec3 center = (min + max) / 2.0;
-	Vec3 extend = (max - min) / 2.0;
+	Vec3 center = (min + max) * 0.5;
+	Vec3 extend = (max - min) * 0.5;
 
 
 	Vec3 newC = center.getTransformed(transform);
 	Vec3 newC = center.getTransformed(transform);
 	Vec3 newE = absM * (extend * transform.getScale());
 	Vec3 newE = absM * (extend * transform.getScale());

+ 172 - 0
src/renderer/Tiler.cpp

@@ -122,6 +122,161 @@ struct UpdateTilesPlanesPerspectiveCameraJob: ThreadJob
 typedef Array<UpdateTilesPlanesPerspectiveCameraJob, ThreadPool::MAX_THREADS>
 typedef Array<UpdateTilesPlanesPerspectiveCameraJob, ThreadPool::MAX_THREADS>
 	UpdateJobArray;
 	UpdateJobArray;
 
 
+//==============================================================================
+#define CHECK_PLANE_PTR(p_) \
+	ANKI_ASSERT(p_ < &tiler->allPlanes[tiler->allPlanes.size()]);
+
+/// Job that updates the left, right, top and buttom tile planes
+struct UpdatePlanesPerspectiveCameraJob: ThreadJob
+{
+	Tiler* tiler = nullptr;
+	PerspectiveCamera* cam = nullptr;
+	Bool frustumChanged = nullptr;
+	const Tiler::PixelArray* pixels = nullptr;
+
+	void operator()(U threadId, U threadsCount)
+	{
+		U64 start, end;
+
+		Transform trf = Transform(cam->getWorldTransform());
+
+		if(frustumChanged)
+		{
+			const F32 fx = cam->getFovX();
+			const F32 fy = cam->getFovY();
+			const F32 n = cam->getNear();
+
+			F32 l = 2.0 * n * tan(fx / 2.0);
+			F32 l6 = l / Tiler::TILES_X_COUNT;
+			F32 o = 2.0 * n * tan(fy / 2.0);
+			F32 o6 = o / Tiler::TILES_Y_COUNT;
+
+			// First the bottom planes
+			choseStartEnd(
+				threadId, threadsCount, Tiler::TILES_Y_COUNT - 1, start, end);
+
+			for(U i = start; i < end; i++)
+			{
+				calcPlaneI(i, o6);
+
+				CHECK_PLANE_PTR(&tiler->planesIW[i]);
+				CHECK_PLANE_PTR(&tiler->planesI[i]);
+				tiler->planesIW[i] = tiler->planesI[i].getTransformed(trf);
+			}
+
+			// Then the left planes
+			choseStartEnd(
+				threadId, threadsCount, Tiler::TILES_X_COUNT - 1, start, end);
+
+			for(U j = start; j < end; j++)
+			{
+				calcPlaneJ(j, l6);
+
+				CHECK_PLANE_PTR(&tiler->planesJW[j]);
+				CHECK_PLANE_PTR(&tiler->planesJ[j]);
+				tiler->planesJW[j] = tiler->planesJ[j].getTransformed(trf);
+			}
+		}
+		else
+		{
+			// First the bottom planes
+			choseStartEnd(
+				threadId, threadsCount, Tiler::TILES_Y_COUNT - 1, start, end);
+
+			for(U i = start; i < end; i++)
+			{
+				CHECK_PLANE_PTR(&tiler->planesIW[i]);
+				CHECK_PLANE_PTR(&tiler->planesI[i]);
+				tiler->planesIW[i] = tiler->planesI[i].getTransformed(trf);
+			}
+
+			// Then the left planes
+			choseStartEnd(
+				threadId, threadsCount, Tiler::TILES_X_COUNT - 1, start, end);
+
+			for(U j = start; j < end; j++)
+			{
+				CHECK_PLANE_PTR(&tiler->planesJW[j]);
+				CHECK_PLANE_PTR(&tiler->planesJ[j]);
+				tiler->planesJW[j] = tiler->planesJ[j].getTransformed(trf);
+			}
+		}
+
+		// Update the near far planes
+		Vec2 rplanes;
+		Renderer::calcPlanes(Vec2(cam->getNear(), cam->getFar()), rplanes);
+
+		choseStartEnd(
+			threadId, threadsCount, Tiler::TILES_COUNT * 2, start, end);
+
+		Plane* planes = tiler->nearFarPlanes;
+		Plane* planesW = tiler->nearFarPlanesW;
+		for(U k = start; k < end; k += 2)
+		{
+			U j = (k / 2) % Tiler::TILES_X_COUNT;
+			U i = (k / 2) / Tiler::TILES_X_COUNT;
+
+			ANKI_ASSERT(planes < &tiler->allPlanes[tiler->allPlanes.size()]);
+			ANKI_ASSERT(planesW < &tiler->allPlanes[tiler->allPlanes.size()]);
+
+			// Calculate depth as you do it for the vertex position inside
+			// the shaders
+			F32 minZ = rplanes.y() / (rplanes.x() + (*pixels)[i][j][0]);
+			F32 maxZ = rplanes.y() / (rplanes.x() + (*pixels)[i][j][1]);
+
+			// Calc the planes
+			CHECK_PLANE_PTR(planes);
+			planes[0] = Plane(Vec3(0.0, 0.0, -1.0), minZ);
+			CHECK_PLANE_PTR(planes + 1);
+			planes[1] = Plane(Vec3(0.0, 0.0, 1.0), -maxZ);
+
+			// Tranform them
+			CHECK_PLANE_PTR(planesW);
+			planesW[0] = planes[0].getTransformed(trf);
+			CHECK_PLANE_PTR(planesW + 1);
+			planesW[1] = planes[1].getTransformed(trf);
+
+			// Advance
+			planes += 2;
+			planesW += 2;
+		}
+	}
+
+	/// Calculate and set a bottom plane
+	void calcPlaneI(U i, const F32 o6)
+	{
+		Vec3 a, b;
+		const F32 n = cam->getNear();
+		Plane& plane = tiler->planesI[i];
+		CHECK_PLANE_PTR(&plane);
+
+		// bottom
+		a = Vec3(0.0, (I(i + 1) - I(Tiler::TILES_Y_COUNT) / 2) * o6, -n);
+		b = Vec3(1.0, 0.0, 0.0).cross(a);
+		b.normalize();
+
+		plane = Plane(b, 0.0);
+	}
+
+	/// Calculate and set a bottom left
+	void calcPlaneJ(U j, const F32 l6)
+	{
+		Vec3 a, b;
+		const F32 n = cam->getNear();
+		Plane& plane = tiler->planesI[j];
+		CHECK_PLANE_PTR(&plane);
+
+		// bottom
+		a = Vec3((I(j + 1) - I(Tiler::TILES_X_COUNT) / 2) * l6, 0.0, -n);
+		b = a.cross(Vec3(0.0, 1.0, 0.0));
+		b.normalize();
+
+		plane = Plane(b, 0.0);
+	}
+};
+
+#undef CHECK_PLANE_PTR
+
 //==============================================================================
 //==============================================================================
 // Statics                                                                     =
 // Statics                                                                     =
 //==============================================================================
 //==============================================================================
@@ -261,6 +416,23 @@ void Tiler::initInternal(Renderer* r_)
 	pbo.create(GL_PIXEL_PACK_BUFFER, 
 	pbo.create(GL_PIXEL_PACK_BUFFER, 
 		TILES_X_COUNT * TILES_Y_COUNT * 2 * sizeof(F32), nullptr);
 		TILES_X_COUNT * TILES_Y_COUNT * 2 * sizeof(F32), nullptr);
 
 
+	// Init planes
+	U planesCount = 
+		(TILES_X_COUNT - 1) // planes J
+		+ (TILES_Y_COUNT - 1)  // planes I
+		+ (TILES_COUNT * 2); // near far planes
+
+	allPlanes.resize(planesCount * 2);
+
+	planesJ = &allPlanes[0];
+	planesI = planesJ + TILES_X_COUNT - 1;
+	nearFarPlanes = planesI + (TILES_Y_COUNT - 1);
+
+	planesW = nearFarPlanes + TILES_COUNT * 2;
+	planesJW = planesW;
+	planesIW = planesJW + TILES_X_COUNT - 1;
+	nearFarPlanesW = planesIW + (TILES_Y_COUNT - 1);
+
 	// Tiles
 	// Tiles
 	initTiles();
 	initTiles();
 }
 }