Browse Source

Frustum culling working

Marko Pintera 11 years ago
parent
commit
331d4ac2aa

+ 2 - 3
BansheeEngine/Source/BsCamera.cpp

@@ -300,13 +300,12 @@ namespace BansheeEngine
 
 
 	void Camera::updateFrustumPlanes() const
 	void Camera::updateFrustumPlanes() const
 	{
 	{
-		updateView();
 		updateFrustum();
 		updateFrustum();
 
 
 		if (mRecalcFrustumPlanes)
 		if (mRecalcFrustumPlanes)
 		{
 		{
 			Vector<Plane> frustumPlanes(6);
 			Vector<Plane> frustumPlanes(6);
-			Matrix4 combo = mProjMatrix * mViewMatrix;
+			Matrix4 combo = mProjMatrix;
 
 
 			frustumPlanes[FRUSTUM_PLANE_LEFT].normal.x = combo[3][0] + combo[0][0];
 			frustumPlanes[FRUSTUM_PLANE_LEFT].normal.x = combo[3][0] + combo[0][0];
 			frustumPlanes[FRUSTUM_PLANE_LEFT].normal.y = combo[3][1] + combo[0][1];
 			frustumPlanes[FRUSTUM_PLANE_LEFT].normal.y = combo[3][1] + combo[0][1];
@@ -341,7 +340,7 @@ namespace BansheeEngine
 			for(UINT32 i = 0; i < 6; i++) 
 			for(UINT32 i = 0; i < 6; i++) 
 			{
 			{
 				float length = frustumPlanes[i].normal.normalize();
 				float length = frustumPlanes[i].normal.normalize();
-				frustumPlanes[i].d /= length;
+				frustumPlanes[i].d /= -length;
 			}
 			}
 
 
 			mFrustum = ConvexVolume(frustumPlanes);
 			mFrustum = ConvexVolume(frustumPlanes);

+ 5 - 4
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -103,13 +103,14 @@ namespace BansheeEngine
 		 * @brief	Updates an existing camera proxy with new data. This includes data that changes
 		 * @brief	Updates an existing camera proxy with new data. This includes data that changes
 		 *			often. For other data it is best to remove old proxy and add new one.
 		 *			often. For other data it is best to remove old proxy and add new one.
 		 *
 		 *
-		 * @param	proxy	Proxy to update.
-		 * @param	camera	World transform matrix of the camera.
-		 * @param	camera	View transform matrix of the camera.
+		 * @param	proxy			Proxy to update.
+		 * @param	worldPosition	World position of the camera.
+		 * @param	worldMatrix		World transform matrix of the camera.
+		 * @param	viewMatrix		View transform matrix of the camera.
 		 *
 		 *
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		void updateCameraProxy(CameraProxyPtr proxy, Matrix4 worldMatrix, Matrix4 viewMatrix);
+		void updateCameraProxy(CameraProxyPtr proxy, Vector3 worldPosition, Matrix4 worldMatrix, Matrix4 viewMatrix);
 
 
 		/**
 		/**
 		 * @brief	Adds a new set of objects to the cameras render queue.
 		 * @brief	Adds a new set of objects to the cameras render queue.

+ 4 - 2
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -170,9 +170,10 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void BansheeRenderer::updateCameraProxy(CameraProxyPtr proxy, Matrix4 worldMatrix, Matrix4 viewMatrix)
+	void BansheeRenderer::updateCameraProxy(CameraProxyPtr proxy, Vector3 worldPosition, Matrix4 worldMatrix, Matrix4 viewMatrix)
 	{
 	{
 		proxy->viewMatrix = viewMatrix;
 		proxy->viewMatrix = viewMatrix;
+		proxy->worldPosition = worldPosition;
 
 
 		const Vector<Plane>& frustumPlanes = proxy->frustum.getPlanes();
 		const Vector<Plane>& frustumPlanes = proxy->frustum.getPlanes();
 		Vector<Plane> worldPlanes;
 		Vector<Plane> worldPlanes;
@@ -297,7 +298,8 @@ namespace BansheeEngine
 				CameraProxyPtr proxy = camera->_getActiveProxy();
 				CameraProxyPtr proxy = camera->_getActiveProxy();
 				assert(proxy != nullptr);
 				assert(proxy != nullptr);
 
 
-				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateCameraProxy, this, proxy, camera->SO()->getWorldTfrm(), camera->getViewMatrix()));
+				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateCameraProxy, this, 
+					proxy, camera->SO()->getWorldPosition(), camera->SO()->getWorldTfrm(), camera->getViewMatrix()));
 
 
 				dirtySceneObjects.push_back(camera->SO());
 				dirtySceneObjects.push_back(camera->SO());
 			}
 			}

+ 4 - 1
BansheeUtility/Include/BsMatrix4.h

@@ -366,11 +366,14 @@ namespace BansheeEngine
         {
         {
 			Vector4 localNormal(p.normal.x, p.normal.y, p.normal.z, 0.0f);
 			Vector4 localNormal(p.normal.x, p.normal.y, p.normal.z, 0.0f);
 			Vector4 localPoint = localNormal * p.d;
 			Vector4 localPoint = localNormal * p.d;
+			localPoint.w = 1.0f;
 
 
-			Vector4 worldNormal = inverse().transpose().multiply3x4(localNormal);
+			Matrix4 itMat = inverse().transpose();
+			Vector4 worldNormal = itMat.multiply3x4(localNormal);
 			Vector4 worldPoint = multiply3x4(localPoint);
 			Vector4 worldPoint = multiply3x4(localPoint);
 
 
 			float d = worldNormal.dot(worldPoint);
 			float d = worldNormal.dot(worldPoint);
+
 			return Plane(worldNormal.x, worldNormal.y, worldNormal.z, d);
 			return Plane(worldNormal.x, worldNormal.y, worldNormal.z, d);
         }
         }
 
 

+ 5 - 0
BansheeUtility/Include/BsPlane.h

@@ -45,6 +45,11 @@ namespace BansheeEngine
          */
          */
         Side getSide(const AABox& box) const;
         Side getSide(const AABox& box) const;
 
 
+        /**
+		 * @brief	Returns the side where the sphere is. The flag BOTH_SIDE indicates an intersecting sphere.
+         */
+		Side getSide(const Sphere& sphere) const;
+
         /**
         /**
          * @brief	Returns a distance from point to plane.
          * @brief	Returns a distance from point to plane.
          *
          *

+ 7 - 13
BansheeUtility/Source/BsConvexVolume.cpp

@@ -17,16 +17,13 @@ namespace BansheeEngine
 
 
 		for (auto& plane : mPlanes)
 		for (auto& plane : mPlanes)
 		{
 		{
-			float dist = center.x * plane.normal.x;
-			dist += center.y * plane.normal.y;
-			dist += center.z * plane.normal.z;
-			dist = dist - plane.d;
+			float dist = center.dot(plane.normal) - plane.d;
 
 
-			float pushOut = absExtents.x * Math::abs(plane.normal.x);
-			pushOut += absExtents.y * Math::abs(plane.normal.y);
-			pushOut += absExtents.z * Math::abs(plane.normal.z);
+			float effectiveRadius = absExtents.x * Math::abs(plane.normal.x);
+			effectiveRadius += absExtents.y * Math::abs(plane.normal.y);
+			effectiveRadius += absExtents.z * Math::abs(plane.normal.z);
 
 
-			if (dist > pushOut)
+			if (dist < -effectiveRadius)
 				return false;
 				return false;
 		}
 		}
 
 
@@ -40,12 +37,9 @@ namespace BansheeEngine
 
 
 		for (auto& plane : mPlanes)
 		for (auto& plane : mPlanes)
 		{
 		{
-			float dist = center.x * plane.normal.x;
-			dist += center.y * plane.normal.y;
-			dist += center.z * plane.normal.z;
-			dist = dist - plane.d;
+			float dist = center.dot(plane.normal) - plane.d;
 
 
-			if (dist > radius)
+			if (dist < -radius)
 				return false;
 				return false;
 		}
 		}
 
 

+ 15 - 0
BansheeUtility/Source/BsPlane.cpp

@@ -80,6 +80,21 @@ namespace BansheeEngine
 		return Plane::BOTH_SIDE;
 		return Plane::BOTH_SIDE;
 	}
 	}
 
 
+	Plane::Side Plane::getSide(const Sphere& sphere) const
+	{
+		// Calculate the distance between box centre and the plane
+		float dist = getDistance(sphere.getCenter());
+		float radius = sphere.getRadius();
+
+		if (dist < -radius)
+			return Plane::NEGATIVE_SIDE;
+
+		if (dist > +radius)
+			return Plane::POSITIVE_SIDE;
+
+		return Plane::BOTH_SIDE;
+	}
+
 	Vector3 Plane::projectVector(const Vector3& point) const
 	Vector3 Plane::projectVector(const Vector3& point) const
 	{
 	{
 		// We know plane normal is unit length, so use simple method
 		// We know plane normal is unit length, so use simple method

+ 0 - 1
Polish.txt

@@ -1,6 +1,5 @@
 Polish TODO:
 Polish TODO:
  - Finalize example with resolution settings and proper GUI
  - Finalize example with resolution settings and proper GUI
- - Finish documentation (BansheeEngine + TODO UNDOCUMENTED)
 
 
  - Add license text to all files
  - Add license text to all files
  - Make a separate release branch with no editor/script stuff, and without .txt files and other development data
  - Make a separate release branch with no editor/script stuff, and without .txt files and other development data