Browse Source

Visibility testing

Panagiotis Christopoulos Charitos 14 years ago
parent
commit
c3adcb3e3c

+ 1 - 1
build/genmakefiledbg

@@ -1,2 +1,2 @@
 #!/bin/sh
-cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=`which clang++` -DBUILD_SHARED_LIBS=ON ..
+cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON ..

+ 1 - 0
src/cln/Collision.h

@@ -6,6 +6,7 @@
 #include "Obb.h"
 #include "Ray.h"
 #include "LineSegment.h"
+#include "PerspectiveCameraShape.h"
 
 
 #endif

+ 1 - 1
src/cln/CollisionShape.h

@@ -21,7 +21,7 @@ class CollisionShape
 			CST_SPHERE,
 			CST_AABB,
 			CST_OBB,
-			CST_PROJECTION_CAMERA_FRUSTRUM
+			CST_PERSPECTIVE_CAMERA_FRUSTRUM
 		};
 
 		CollisionShape(CollisionShapeType cid_)

+ 0 - 0
src/cln/ProjectionCameraShape.cpp → src/cln/PerspectiveCameraShape.cpp


+ 6 - 6
src/cln/ProjectionCameraShape.h → src/cln/PerspectiveCameraShape.h

@@ -9,17 +9,17 @@
 /// @{
 
 /// Collision shape for the projection cameras
-class ProjectionCameraShape: public CollisionShape
+class PerspectiveCameraShape: public CollisionShape
 {
 	public:
 		/// Default constructor
-		ProjectionCameraShape()
-		:	CollisionShape(CST_PROJECTION_CAMERA_FRUSTRUM)
+		PerspectiveCameraShape()
+		:	CollisionShape(CST_PERSPECTIVE_CAMERA_FRUSTRUM)
 		{}
 
-		ProjectionCameraShape(float fovX, float fovY, float zNear,
+		PerspectiveCameraShape(float fovX, float fovY, float zNear,
 			float zFar, const Transform& trf)
-		:	CollisionShape(CST_PROJECTION_CAMERA_FRUSTRUM)
+		:	CollisionShape(CST_PERSPECTIVE_CAMERA_FRUSTRUM)
 		{
 			setAll(fovX, fovY, zNear, zFar, trf);
 		}
@@ -27,7 +27,7 @@ class ProjectionCameraShape: public CollisionShape
 		/// @copydoc CollisionShape::testPlane
 		float testPlane(const Plane& p) const;
 
-		ProjectionCameraShape getTransformed(const Transform& trf) const;
+		PerspectiveCameraShape getTransformed(const Transform& trf) const;
 
 		/// Set all
 		void setAll(float fovX, float fovY, float zNear,

+ 2 - 2
src/r/Dbg.cpp

@@ -301,12 +301,12 @@ void Dbg::run()
 				break;
 			case SceneNode::SNT_SKIN_NODE:
 			{
-				const SkinNode& node_ = static_cast<const SkinNode&>(*node);
+				/*const SkinNode& node_ = static_cast<const SkinNode&>(*node);
 				sceneDbgDrawer.drawSkinNodeSkeleton(node_);
 				if(showVisibilityBoundingShapesFlag)
 				{
 					collisionDbgDrawer.draw(node_.getVisibilityShapeWSpace());
-				}
+				}*/
 				break;
 			}
 			default:

+ 12 - 2
src/r/Is.cpp

@@ -207,9 +207,11 @@ void Is::pointLightPass(const PointLight& light)
 void Is::spotLightPass(const SpotLight& light)
 {
 	const Camera& cam = r.getCamera();
+	bool withShadow = light.getCastShadow() && sm.getEnabled() &&
+		(light.getVisibleMsRenderableNodes().size() > 0);
 
 	// shadow mapping
-	if(light.getCastShadow() && sm.getEnabled())
+	if(withShadow)
 	{
 		Vec3 zAxis = light.getWorldTransform().getRotation().getColumn(2);
 		LineSegment seg(light.getWorldTransform().getOrigin(),
@@ -242,7 +244,7 @@ void Is::spotLightPass(const SpotLight& light)
 	// shader prog
 	const ShaderProgram* shdr;
 
-	if(light.getCastShadow() && sm.getEnabled())
+	if(withShadow)
 	{
 		shdr = spotLightShadowSProg.get();
 	}
@@ -347,11 +349,19 @@ void Is::run()
 	BOOST_FOREACH(const PointLight* light,
 		r.getCamera().getVisiblePointLights())
 	{
+		if(light->getVisibleMsRenderableNodes().size() == 0)
+		{
+			continue;
+		}
 		pointLightPass(*light);
 	}
 
 	BOOST_FOREACH(const SpotLight* light, r.getCamera().getVisibleSpotLights())
 	{
+		/*if(light->getVisibleMsRenderableNodes() == 0)
+		{
+			continue;
+		}*/
 		spotLightPass(*light);
 	}
 	

+ 2 - 0
src/r/Sm.cpp

@@ -106,6 +106,8 @@ void Sm::run(const Light& light, float distance)
 		return;
 	}
 
+	ASSERT(light.getVisibleMsRenderableNodes().size() == 0);
+
 	//
 	// Determine the level
 	//

+ 5 - 16
src/scene/Camera.h

@@ -78,7 +78,10 @@ class Camera: public SceneNode, public VisibilityInfo
 			return invProjectionMat;
 		}
 
-		const Plane& getWSpaceFrustumPlane(FrustrumPlanes id) const;
+		const Plane& getWSpaceFrustumPlane(FrustrumPlanes id) const
+		{
+			return wspaceFrustumPlanes[id];
+		}
 		/// @}
 
 		void lookAtPoint(const Vec3& point);
@@ -86,7 +89,7 @@ class Camera: public SceneNode, public VisibilityInfo
 		/// This does:
 		/// - Update view matrix
 		/// - Update frustum planes
-		void moveUpdate();
+		virtual void moveUpdate();
 
 		/// @name Frustum checks
 		/// @{
@@ -94,10 +97,6 @@ class Camera: public SceneNode, public VisibilityInfo
 		/// Check if the given camera is inside the frustum clipping planes.
 		/// This is used mainly to test if the projected lights are visible
 		bool insideFrustum(const CollisionShape& vol) const;
-
-		/// Check if another camera is inside our view (used for projected
-		/// lights)
-		bool insideFrustum(const Camera& cam) const;
 		/// @}
 
 	protected:
@@ -129,10 +128,6 @@ class Camera: public SceneNode, public VisibilityInfo
 		void updateViewMatrix();
 		void updateWSpaceFrustumPlanes();
 
-		/// Get the edge points of the camera
-		virtual void getExtremePoints(Vec3* pointsArr,
-			uint& pointsNum) const = 0;
-
 	private:
 		CameraType type;
 };
@@ -149,12 +144,6 @@ inline Camera::Camera(CameraType t, Scene& scene, ulong flags,
 }
 
 
-inline const Plane& Camera::getWSpaceFrustumPlane(FrustrumPlanes id) const
-{
-	return wspaceFrustumPlanes[id];
-}
-
-
 inline void Camera::setZNear(float znear_)
 {
 	zNear = znear_;

+ 3 - 2
src/scene/ModelNode.h

@@ -42,9 +42,10 @@ class ModelNode: public SceneNode
 			return *model;
 		}
 
-		const Obb& getVisibilityShapeWSpace() const
+		const CollisionShape*
+			getVisibilityCollisionShapeWorldSpace() const
 		{
-			return visibilityShapeWSpace;
+			return &visibilityShapeWSpace;
 		}
 		/// @}
 

+ 5 - 2
src/scene/ModelPatchNode.h

@@ -14,11 +14,14 @@ class ModelPatchNode: public PatchNode
 	public:
 		ModelPatchNode(const ModelPatch& modelPatch, ModelNode& parent);
 
-		const Obb& getVisibilityShapeWSpace() const
+		/// @copydoc SceneNode::getVisibilityCollisionShapeWorldSpace
+		const CollisionShape*
+			getVisibilityCollisionShapeWorldSpace() const
 		{
-			return visibilityShapeWSpace;
+			return &visibilityShapeWSpace;
 		}
 
+
 		void init(const char*)
 		{}
 

+ 0 - 20
src/scene/OrthographicCamera.cpp

@@ -75,23 +75,3 @@ void OrthographicCamera::calcProjectionMatrix()
 	projectionMat = ortho(left, right, bottom, top, zNear, zFar);
 	invProjectionMat = projectionMat.getInverse();
 }
-
-
-//==============================================================================
-// getExtremePoints                                                            =
-//==============================================================================
-void OrthographicCamera::getExtremePoints(Vec3* pointsArr,
-	uint& pointsNum) const
-{
-	pointsArr[0] = Vec3(right, top, -zNear);
-	pointsArr[1] = Vec3(left, top, -zNear);
-	pointsArr[2] = Vec3(left, bottom, -zNear);
-	pointsArr[3] = Vec3(right, bottom, -zNear);
-	pointsArr[4] = Vec3(right, top, -zFar);
-	pointsArr[5] = Vec3(left, top, -zFar);
-	pointsArr[6] = Vec3(left, bottom, -zFar);
-	pointsArr[7] = Vec3(right, bottom, -zFar);
-
-	pointsNum = 8;
-}
-

+ 16 - 7
src/scene/OrthographicCamera.h

@@ -14,16 +14,28 @@ class OrthographicCamera: public Camera
 
 		/// @name Accessors
 		/// @{
-		float getLeft() const {return left;}
+		float getLeft() const
+		{
+			return left;
+		}
 		void setLeft(float f);
 
-		float getRight() const {return right;}
+		float getRight() const
+		{
+			return right;
+		}
 		void setRight(float f);
 
-		float getTop() const {return top;}
+		float getTop() const
+		{
+			return top;
+		}
 		void setTop(float f);
 
-		float getBottom() const {return bottom;}
+		float getBottom() const
+		{
+			return bottom;
+		}
 		void setBottom(float f);
 		/// @}
 
@@ -55,9 +67,6 @@ class OrthographicCamera: public Camera
 
 		/// Implements Camera::calcProjectionMatrix
 		void calcProjectionMatrix();
-
-		/// Implements Camera::getExtremePoints
-		void getExtremePoints(Vec3* pointsArr, uint& pointsNum) const;
 };
 
 

+ 0 - 26
src/scene/PerspectiveCamera.cpp

@@ -68,29 +68,3 @@ void PerspectiveCamera::calcLSpaceFrustumPlanes()
 	// far
 	lspaceFrustumPlanes[FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), -zFar);
 }
-
-
-//==============================================================================
-// getExtremePoints                                                            =
-//==============================================================================
-void PerspectiveCamera::getExtremePoints(Vec3* points, uint& pointsNum) const
-{
-	float x = getZFar() / tan((Math::PI - getFovX()) / 2.0);
-	float y = tan(getFovY() / 2.0) * getZFar();
-	float z = -getZFar();
-
-	// the actual points in local space
-	points[0] = Vec3(x, y, z); // top right
-	points[1] = Vec3(-x, y, z); // top left
-	points[2] = Vec3(-x, -y, z); // bottom left
-	points[3] = Vec3(x, -y, z); // bottom right
-	points[4] = getWorldTransform().getOrigin(); // eye (already in world space)
-
-	// transform them to the given camera's world space (exept the eye)
-	for(uint i = 0; i < 4; i++)
-	{
-		points[i].transform(getWorldTransform());
-	}
-
-	pointsNum = 5;
-}

+ 31 - 6
src/scene/PerspectiveCamera.h

@@ -2,6 +2,7 @@
 #define PERSPECTIVE_CAMERA_H
 
 #include "Camera.h"
+#include "cln/Collision.h"
 
 
 /// @todo
@@ -10,8 +11,6 @@ class PerspectiveCamera: public Camera
 	public:
 		PerspectiveCamera(Scene& scene, ulong flags, SceneNode* parent);
 
-		void init(const char*) {}
-
 		/// @name Accessors
 		/// @{
 		float getFovX() const
@@ -27,11 +26,29 @@ class PerspectiveCamera: public Camera
 		void setFovY(float fovy);
 		/// @}
 
+		void moveUpdate()
+		{
+			Camera::moveUpdate();
+			wspaceCShape =
+				lspaceCShape.getCollisionShapeType(getWorldTransform());
+		}
+
+		/// @copydoc SceneNode::getVisibilityCollisionShapeWorldSpace
+		const CollisionShape* getVisibilityCollisionShapeWorldSpace() const
+		{
+			return &wspaceCShape;
+		}
+
+		void init(const char*)
+		{}
+
 		void setAll(float fovx, float fovy, float znear, float zfar);
 
 	private:
 		/// @name Data
 		/// @{
+		PerspectiveCameraShape lspaceCShape;
+		PerspectiveCameraShape wspaceCShape;
 
 		/// fovX is the angle in the y axis (imagine the cam positioned in
 		/// the default OGL pos) Note that fovX > fovY (most of the time) and
@@ -46,8 +63,17 @@ class PerspectiveCamera: public Camera
 		/// Implements Camera::calcProjectionMatrix
 		void calcProjectionMatrix();
 
-		/// Implements Camera::getExtremePoints
-		void getExtremePoints(Vec3* pointsArr, uint& pointsNum) const;
+		/// Update:
+		/// - The projection matrix
+		/// - The planes
+		/// - The collision shape
+		void updateLocals()
+		{
+			calcProjectionMatrix();
+			calcLSpaceFrustumPlanes();
+			lspaceCShape.setAll(fovX, fovY, zNear, zFar,
+				Transform::getIdentity());
+		}
 };
 
 
@@ -62,8 +88,7 @@ inline PerspectiveCamera::PerspectiveCamera(Scene& scene, ulong flags,
 inline void PerspectiveCamera::setFovX(float fovx_)
 {
 	fovX = fovx_;
-	calcProjectionMatrix();
-	calcLSpaceFrustumPlanes();
+	update();
 }
 
 

+ 28 - 3
src/scene/PointLight.h

@@ -2,6 +2,7 @@
 #define POINT_LIGHT_H
 
 #include "Light.h"
+#include "cln/Sphere.h"
 
 
 /// Point light. Defined by its radius
@@ -10,14 +11,37 @@ class PointLight: public Light
 	public:
 		PointLight(Scene& scene, ulong flags, SceneNode* parent);
 
-		float getRadius() const {return radius;}
-		float& getRadius() {return radius;}
-		void setRadius(float x) {radius = x;}
+		/// @name Accessors
+		/// @{
+		float getRadius() const
+		{
+			return radius;
+		}
+		void setRadius(float x)
+		{
+			radius = x;
+			lspaceCShape = Sphere(Vec3(0.0), radius);
+		}
+		/// @}
 
 		void init(const char* filename);
 
+		/// @copydoc SceneNode::getVisibilityCollisionShapeWorldSpace
+		const CollisionShape*
+			getVisibilityCollisionShapeWorldSpace() const
+		{
+			return &wspaceCShape;
+		}
+
+		void moveUpdate()
+		{
+			wspaceCShape = lspaceCShape.getTransformed();
+		}
+
 	private:
 		float radius;
+		Sphere lspaceCShape;
+		Sphere wspaceCShape;
 };
 
 
@@ -34,6 +58,7 @@ inline void PointLight::init(const char* filename)
 		throw EXCEPTION("Light data is wrong type");
 	}
 	radius = lightData->getRadius();
+	lspaceCShape = Sphere(Vec3(0.0), radius);
 }
 
 

+ 1 - 1
src/scene/SceneNode.h

@@ -125,7 +125,7 @@ class SceneNode
 			return children;
 		}
 
-		/// Get the collision shape used for visibility testing
+		/// Get the collision shape to for visibility testing
 		virtual const CollisionShape*
 			getVisibilityCollisionShapeWorldSpace() const
 		{

+ 3 - 2
src/scene/SkinNode.h

@@ -83,9 +83,10 @@ class SkinNode: public SceneNode
 				patches.end());
 		}
 
-		const Obb& getVisibilityShapeWSpace() const
+		const CollisionShape*
+			getVisibilityCollisionShapeWorldSpace() const
 		{
-			return visibilityShapeWSpace;
+			return &visibilityShapeWSpace;
 		}
 
 		const Skin& getSkin() const

+ 44 - 10
src/scene/SpotLight.h

@@ -10,27 +10,61 @@ class SpotLight: public Light
 {
 	public:
 		SpotLight(Scene& scene, ulong flags, SceneNode* parent);
-		~SpotLight() {}
+		~SpotLight()
+		{}
 
 		void init(const char* filename);
 
 		/// @name Accessors
 		/// @{
-		float getDistance() const {return camera->getZFar();}
-		void setDistance(float d) {camera->setZFar(d);}
+		float getDistance() const
+		{
+			return camera->getZFar();
+		}
+		void setDistance(float d)
+		{
+			camera->setZFar(d);
+		}
 
-		float getFovX() const {return camera->getFovX();}
-		void setFovX(float f) {camera->setFovX(f);}
+		float getFovX() const
+		{
+			return camera->getFovX();
+		}
+		void setFovX(float f)
+		{
+			camera->setFovX(f);
+		}
 
-		float getFovY() const {return camera->getFovY();}
-		void setFovY(float f) {camera->setFovY(f);}
+		float getFovY() const
+		{
+			return camera->getFovY();
+		}
+		void setFovY(float f)
+		{
+			camera->setFovY(f);
+		}
 
-		const Texture& getTexture() const {return lightData->getTexture();}
+		const Texture& getTexture() const
+		{
+			return lightData->getTexture();
+		}
 
-		const Camera& getCamera() const {return *camera;}
-		Camera& getCamera() {return *camera;}
+		const Camera& getCamera() const
+		{
+			return *camera;
+		}
+		Camera& getCamera()
+		{
+			return *camera;
+		}
 		/// @}
 
+		const CollisionShape*
+			getVisibilityCollisionShapeWorldSpace() const
+		{
+			return camera->getVisibilityCollisionShapeWorldSpace();
+		}
+
 	private:
 		PerspectiveCamera* camera;
 };