Przeglądaj źródła

Visibility determination

Panagiotis Christopoulos Charitos 15 lat temu
rodzic
commit
f3599e4047
2 zmienionych plików z 108 dodań i 6 usunięć
  1. 86 1
      src/Scene/VisibilityTester.cpp
  2. 22 5
      src/Scene/VisibilityTester.h

+ 86 - 1
src/Scene/VisibilityTester.cpp

@@ -1,5 +1,20 @@
 #include "VisibilityTester.h"
 #include "Scene.h"
+#include "ModelNode.h"
+#include "ModelNodePatch.h"
+#include "Material.h"
+#include "Sphere.h"
+#include "PointLight.h"
+#include "SpotLight.h"
+
+
+//======================================================================================================================
+// CmpLength::operator()                                                                                               =
+//======================================================================================================================
+inline bool VisibilityTester::CmpLength::operator()(const SceneRenderable* a, const SceneRenderable* b) const
+{
+	return (a->getWorldTransform().origin - o).getLengthSquared() < (b->getWorldTransform().origin - o).getLengthSquared();
+}
 
 
 //======================================================================================================================
@@ -15,5 +30,75 @@ VisibilityTester::VisibilityTester(const Scene& scene_):
 //======================================================================================================================
 void VisibilityTester::test(const Camera& cam)
 {
-	//Scene
+	//
+	// Clean
+	//
+	msRenderables.clear();
+	bsRenderables.clear();
+	pointLights.clear();
+	spotLights.clear();
+
+	//
+	// Collect the SceneRenderable
+	//
+	Scene::Types<ModelNode>::ConstIterator it = scene.getModelNodes().begin();
+	for(; it != scene.getModelNodes().end(); it++)
+	{
+		boost::ptr_vector<ModelNodePatch>::const_iterator it2 = (*it)->getModelNodePatches().begin();
+		for(; it2 != (*it)->getModelNodePatches().end(); it2++)
+		{
+			const ModelNodePatch& modelNodePatch = *it2;
+
+			if(modelNodePatch.getCpMtl().isBlendingEnabled())
+			{
+				bsRenderables.push_back(&modelNodePatch);
+			}
+			else
+			{
+				msRenderables.push_back(&modelNodePatch);
+			}
+		}
+	}
+
+	//
+	// Sort the renderables from closest to the camera to the farthest
+	//
+	std::sort(msRenderables.begin(), msRenderables.end(), CmpLength(cam.getWorldTransform().origin));
+	std::sort(bsRenderables.begin(), bsRenderables.end(), CmpLength(cam.getWorldTransform().origin));
+
+	//
+	// Collect the lights
+	//
+	Scene::Types<Light>::ConstIterator itl = scene.getLights().begin();
+	for(; itl != scene.getLights().end(); itl++)
+	{
+		const Light& light = *(*itl);
+
+		// Point
+		switch(light.getType())
+		{
+			case Light::LT_POINT:
+			{
+				const PointLight& pointl = static_cast<const PointLight&>(light);
+
+				Sphere sphere(pointl.getWorldTransform().origin, pointl.getRadius());
+				if(cam.insideFrustum(sphere))
+				{
+					pointLights.push_back(&pointl);
+				}
+				break;
+			}
+			// Spot
+			case Light::LT_SPOT:
+			{
+				const SpotLight& spotl = static_cast<const SpotLight&>(light);
+
+				if(cam.insideFrustum(spotl.getCamera()))
+				{
+					spotLights.push_back(&spotl);
+				}
+				break;
+			}
+		}
+	}
 }

+ 22 - 5
src/Scene/VisibilityTester.h

@@ -3,13 +3,17 @@
 
 #include <deque>
 #include "Properties.h"
+#include "Math.h"
 
 
 class Camera;
 class Scene;
 class SceneRenderable;
+class SpotLight;
+class PointLight;
 
 
+/// Performs visibility determination tests and fills a few containers with the visible scene nodes
 class VisibilityTester
 {
 	public:
@@ -18,26 +22,39 @@ class VisibilityTester
 		class Types
 		{
 			public:
-				typedef std::deque<Type*> Container;
+				typedef std::deque<const Type*> Container;
 				typedef typename Container::iterator Iterator;
 				typedef typename Container::const_iterator ConstIterator;
 		};
 
+		/// Constructor
 		VisibilityTester(const Scene& scene);
 
 		/// @name Accessors
 		/// @{
-		GETTER_R(Types<SceneRenderable>::Container, renderables, getRenderables)
-		GETTER_R(Types<SceneRenderable>::Container, lights, getLights)
+		GETTER_R(Types<SceneRenderable>::Container, msRenderables, getMsRenderables)
+		GETTER_R(Types<SceneRenderable>::Container, bsRenderables, getBsRenderables)
+		GETTER_R(Types<PointLight>::Container, pointLights, getPointLights)
+		GETTER_R(Types<SpotLight>::Container, spotLights, getSpotLights)
 		/// @}
 
 		void test(const Camera& cam);
 
 	private:
+		/// Used in sorting. Compare the length of 2 nodes from the camera
+		struct CmpLength
+		{
+			Vec3 o; ///< The camera origin
+			CmpLength(Vec3 o_): o(o_) {}
+			bool operator()(const SceneRenderable* a, const SceneRenderable* b) const;
+		};
+
 		const Scene& scene; ///< Know your father
 
-		Types<SceneRenderable>::Container renderables;
-		Types<SceneRenderable>::Container lights;
+		Types<SceneRenderable>::Container msRenderables;
+		Types<SceneRenderable>::Container bsRenderables;
+		Types<PointLight>::Container pointLights;
+		Types<SpotLight>::Container spotLights;
 };