Browse Source

Major Scene changes and integration of visibility determination

Panagiotis Christopoulos Charitos 15 năm trước cách đây
mục cha
commit
5b5d183892

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 2
build/debug/Makefile


+ 1 - 1
build/debug/gen.cfg.py

@@ -9,6 +9,6 @@ executableName = "anki"
 
 compiler = "g++"
 
-compilerFlags = "-DDEBUG_ENABLED=1 -DPLATFORM_LINUX -DREVISION=\\\"`svnversion -c ../..`\\\" -c -pedantic-errors -pedantic -ansi -Wall -Wextra -W -Wno-long-long -pipe -g3 -pg -fsingle-precision-constant"
+compilerFlags = "-DDEBUG_ENABLED=1 -DPLATFORM_LINUX -DMATH_INTEL_SIMD -DREVISION=\\\"`svnversion -c ../..`\\\" -c -pedantic-errors -pedantic -ansi -Wall -Wextra -W -Wno-long-long -pipe -g3 -pg -fsingle-precision-constant -msse4"
 
 linkerFlags = "-rdynamic -pg -L../../extern/lib-x86-64-linux -Wl,-Bstatic -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath -lGLEW -lGLU -Wl,-Bdynamic -lGL -ljpeg -lSDL -lpng -lpython2.6 -lboost_system -lboost_python -lboost_filesystem -lboost_thread"

+ 4 - 4
src/Collision/CollisionShape.h

@@ -1,13 +1,11 @@
 #ifndef COLLISION_SHAPE
 #define COLLISION_SHAPE
 
-#include "Properties.h"
-
 
 class Plane;
 
 
-/// Abstact class for collision shapes
+/// Abstract class for collision shapes
 class CollisionShape
 {
 	public:
@@ -22,9 +20,11 @@ class CollisionShape
 			CST_NUM
 		};
 
-	PROPERTY_R(CollisionShapeType, type, getType)
+	CollisionShapeType getType() const {return type;}
 
 	public:
+		CollisionShapeType type;
+
 		CollisionShape(CollisionShapeType type_): type(type_) {}
 
 		/// If the bounding volume intersects with the plane then the func returns 0, else it returns the distance. If the

+ 35 - 5
src/Collision/Sphere.cpp

@@ -5,15 +5,43 @@
 //======================================================================================================================
 // getTransformed                                                                                                      =
 //======================================================================================================================
-Sphere Sphere::getTransformed(const Vec3& translate, const Mat3& rotate, float scale) const
+Sphere Sphere::getTransformed(const Transform& transform) const
 {
 	Sphere newSphere;
-	newSphere.center = center.getTransformed(translate, rotate, scale);
-	newSphere.radius = radius * scale;
+	newSphere.center = center.getTransformed(transform.origin, transform.rotation, transform.scale);
+	newSphere.radius = radius * transform.scale;
 	return newSphere;
 }
 
 
+//======================================================================================================================
+// getCompoundSphere                                                                                                   =
+//======================================================================================================================
+Sphere Sphere::getCompoundSphere(const Sphere& b) const
+{
+	const Sphere& a = *this;
+
+	Vec3 c = b.getCenter() - a.getCenter();
+	float cLen = c.getLength();
+
+	if(cLen + b.getRadius() < a.getRadius())
+	{
+		return a;
+	}
+	else if(cLen + a.getRadius() < b.getRadius())
+	{
+		return b;
+	}
+
+	Vec3 bnorm = c / cLen;
+
+	Vec3 ca = (-bnorm) * a.getRadius() + a.getCenter();
+	Vec3 cb = (bnorm) * b.getRadius() + b.getCenter();
+
+	return Sphere((ca + cb) / 2.0, (ca - cb).getLength() / 2.0);
+}
+
+
 //======================================================================================================================
 // testPlane                                                                                                           =
 //======================================================================================================================
@@ -36,7 +64,7 @@ float Sphere::testPlane(const Plane& plane) const
 }
 
 //======================================================================================================================
-//                                                                                                                     =
+// set                                                                                                                 =
 //======================================================================================================================
 void Sphere::set(const float* pointer, size_t stride, int count)
 {
@@ -68,14 +96,16 @@ void Sphere::set(const float* pointer, size_t stride, int count)
 
 	tmpPtr = (void*)pointer;
 	float maxDist = (*((Vec3*)tmpPtr) - center).getLengthSquared(); // max distance between center and the vec3 arr
-	for(int i=1; i<count; i++)
+	for(int i = 1; i < count; i++)
 	{
 		tmpPtr = (char*)tmpPtr + stride;
 
 		const Vec3& vertco = *((Vec3*)tmpPtr);
 		float dist = (vertco - center).getLengthSquared();
 		if(dist > maxDist)
+		{
 			maxDist = dist;
+		}
 	}
 
 	radius = M::sqrt(maxDist);

+ 13 - 4
src/Collision/Sphere.h

@@ -12,9 +12,6 @@ class Plane;
 /// Sphere collision shape
 class Sphere: public CollisionShape
 {
-	PROPERTY_RW(Vec3, center, getCenter, setCenter)
-	PROPERTY_RW(float, radius, getRadius, setRadius)
-
 	public:
 		/// Default constructor
 		Sphere(): CollisionShape(CST_SPHERE) {}
@@ -25,15 +22,27 @@ class Sphere: public CollisionShape
 		/// Constructor
 		Sphere(const Vec3& center_, float radius_);
 
+		/// @name Accessors
+		/// @{
+		GETTER_SETTER(Vec3, center, getCenter, setCenter)
+		GETTER_SETTER_BY_VAL(float, radius, getRadius, setRadius)
+		/// @}
+
 		/// @see set
 		Sphere(const float* pointer, size_t stride, int count);
 
-		Sphere getTransformed(const Vec3& translate, const Mat3& rotate, float scale) const;
+		Sphere getTransformed(const Transform& transform) const;
+
+		/// Get the sphere that includes this sphere and the given
+		Sphere getCompoundSphere(const Sphere& b) const;
 
 		/// @see CollisionShape::testPlane
 		float testPlane(const Plane& plane) const;
 
 	private:
+		Vec3 center;
+		float radius;
+
 		/// Set from Vec3 array
 		/// @param pointer The start of the array
 		/// @param stride The space between the elements

+ 3 - 1
src/Main.cpp

@@ -118,7 +118,8 @@ void init()
 	//Ui::init();
 
 	// camera
-	Camera* cam = new Camera(MainRendererSingleton::getInstance().getAspectRatio()*toRad(60.0), toRad(60.0), 0.5, 200.0, false, NULL);
+	Camera* cam = new Camera(false, NULL);
+	cam->setAll(MainRendererSingleton::getInstance().getAspectRatio()*toRad(60.0), toRad(60.0), 0.5, 200.0);
 	cam->moveLocalY(3.0);
 	cam->moveLocalZ(5.7);
 	cam->moveLocalX(-0.3);
@@ -313,6 +314,7 @@ void mainLoop()
 		SceneSingleton::getInstance().getPhysics().update(crntTime);
 		SceneSingleton::getInstance().updateAllControllers();
 		SceneSingleton::getInstance().updateAllWorldStuff();
+		SceneSingleton::getInstance().doVisibilityTests(*AppSingleton::getInstance().getActiveCam());
 
 		MainRendererSingleton::getInstance().render(*AppSingleton::getInstance().getActiveCam());
 

+ 4 - 4
src/Renderer/Bs.cpp

@@ -82,7 +82,7 @@ void Bs::init(const RendererInitializer& /*initializer*/)
 //======================================================================================================================
 void Bs::run()
 {
-	Renderer::setViewport(0, 0, r.getWidth(), r.getHeight());
+	/*Renderer::setViewport(0, 0, r.getWidth(), r.getHeight());
 
 	glDepthMask(false);
 
@@ -91,8 +91,8 @@ void Bs::run()
 	for(; it != SceneSingleton::getInstance().getModelNodes().end(); ++it)
 	{
 		const ModelNode& mn = *(*it);
-		boost::ptr_vector<ModelNodePatch>::const_iterator it = mn.getModelNodePatches().begin();
-		for(; it != mn.getModelNodePatches().end(); it++)
+		boost::ptr_vector<ModelNodePatch>::const_iterator it = mn.getModelPatchNodes().begin();
+		for(; it != mn.getModelPatchNodes().end(); it++)
 		{
 			const ModelNodePatch& sm = *it;
 
@@ -164,5 +164,5 @@ void Bs::run()
 
 	glDepthMask(true);
 	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // the rendering above fucks the polygon mode
-	Fbo::unbind();
+	Fbo::unbind();*/
 }

+ 0 - 28
src/Renderer/Dbg.cpp

@@ -238,34 +238,6 @@ void Dbg::init(const RendererInitializer& initializer)
 }
 
 
-/*Sphere Dbg::getCommonSphere(const Sphere& a, const Sphere& b)
-{
-	Vec3 bridge = b.getCenter() - a.getCenter();
-	float blen = bridge.getLength();
-
-	if(blen + b.getRadius() < a.getRadius())
-	{
-		return a;
-	}
-	else if(blen + a.getRadius() < b.getRadius())
-	{
-		return b;
-	}
-
-	Vec3 bnorm = bridge / blen;
-
-	Vec3 ca = (-bnorm) * a.getRadius() + a.getCenter();
-	Vec3 cb = (bnorm) * b.getRadius() + b.getCenter();
-
-	setColor(Vec4(1.0));
-	setModelMat(Mat4(ca));
-	drawSphere(0.01);
-	setModelMat(Mat4(cb));
-	drawSphere(0.01);
-
-	return Sphere((ca + cb) / 2.0, (ca - cb).getLength() / 2.0);
-}*/
-
 //======================================================================================================================
 // runStage                                                                                                            =
 //======================================================================================================================

+ 16 - 38
src/Renderer/Is.cpp

@@ -1,4 +1,5 @@
 #include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
 #include "Is.h"
 #include "Renderer.h"
 #include "Camera.h"
@@ -202,16 +203,10 @@ void Is::ambientPass(const Vec3& color)
 //======================================================================================================================
 // pointLightPass                                                                                                      =
 //======================================================================================================================
-void Is::pointLightPass(const PointLight& light)
+void Is::pointLightPass(const VisibilityTester::VisibleLight<PointLight>& vlight)
 {
 	const Camera& cam = r.getCamera();
-
-	// frustum test
-	Sphere sphere(light.getWorldTransform().origin, light.getRadius());
-	if(!cam.insideFrustum(sphere))
-	{
-		return;
-	}
+	const PointLight& light = vlight.getLight();
 
 	// stencil optimization
 	smo.run(light);
@@ -239,20 +234,15 @@ void Is::pointLightPass(const PointLight& light)
 //======================================================================================================================
 // spotLightPass                                                                                                       =
 //======================================================================================================================
-void Is::spotLightPass(const SpotLight& light)
+void Is::spotLightPass(const VisibilityTester::VisibleLight<SpotLight>& vlight)
 {
 	const Camera& cam = r.getCamera();
-
-	// frustum test
-	if(!cam.insideFrustum(light.getCamera()))
-	{
-		return;
-	}
+	const SpotLight& light = vlight.getLight();
 
 	// shadow mapping
 	if(light.castsShadow() && sm.isEnabled())
 	{
-		sm.run(light.getCamera());
+		sm.run(light.getCamera(), vlight.getRenderables());
 
 		// restore the IS FBO
 		fbo.bind();
@@ -345,30 +335,18 @@ void Is::run()
 	calcPlanes();
 
 	// for all lights
-	Scene::Types<Light>::ConstIterator it = SceneSingleton::getInstance().getLights().begin();
-	for(; it != SceneSingleton::getInstance().getLights().end(); it++)
+	BOOST_FOREACH(const VisibilityTester::VisibleLight<PointLight> light, 
+	              SceneSingleton::getInstance().getVisibilityTester().getPointLights())
+	{
+		pointLightPass(light);
+	}
+	
+	BOOST_FOREACH(const VisibilityTester::VisibleLight<SpotLight> light, 
+	              SceneSingleton::getInstance().getVisibilityTester().getSpotLights())
 	{
-		const Light& light = *(*it);
-		switch(light.getType())
-		{
-			case Light::LT_POINT:
-			{
-				const PointLight& pointl = static_cast<const PointLight&>(light);
-				pointLightPass(pointl);
-				break;
-			}
-
-			case Light::LT_SPOT:
-			{
-				const SpotLight& projl = static_cast<const SpotLight&>(light);
-				spotLightPass(projl);
-				break;
-			}
-
-			default:
-				RASSERT_THROW_EXCEPTION("WTF?");
-		}
+		spotLightPass(light);
 	}
+	
 
 	glDisable(GL_STENCIL_TEST);
 

+ 3 - 2
src/Renderer/Is.h

@@ -11,6 +11,7 @@
 #include "Vao.h"
 #include "Sm.h"
 #include "Smo.h"
+#include "VisibilityTester.h"
 
 
 class PointLight;
@@ -65,10 +66,10 @@ class Is: private RenderingPass
 		void ambientPass(const Vec3& color);
 
 		/// The point light pass
-		void pointLightPass(const PointLight& light);
+		void pointLightPass(const VisibilityTester::VisibleLight<PointLight>& vlight);
 
 		/// The spot light pass
-		void spotLightPass(const SpotLight& light);
+		void spotLightPass(const VisibilityTester::VisibleLight<SpotLight>& vlight);
 
 		/// Used in @ref init
 		void initFbo();

+ 7 - 1
src/Renderer/Ms.cpp

@@ -1,8 +1,11 @@
+#include <boost/foreach.hpp>
 #include "Ms.h"
 #include "Renderer.h"
 #include "Camera.h"
 #include "Ez.h"
 #include "ModelNode.h"
+#include "Scene.h"
+#include "RenderableNode.h"
 
 
 //======================================================================================================================
@@ -94,7 +97,10 @@ void Ms::run()
 	}
 
 	// render all
-	r.renderAllModelNodes(r.getCamera(), Renderer::MNRT_MS);
+	BOOST_FOREACH(const RenderableNode* node, SceneSingleton::getInstance().getVisibilityTester().getMsRenderables())
+	{
+		r.getSceneDrawer().renderRenderableNode(*node, r.getCamera(), SceneDrawer::RPT_COLOR);
+	}
 
 	// restore depth
 	if(ez.isEnabled())

+ 2 - 273
src/Renderer/Renderer.cpp

@@ -20,7 +20,8 @@ Renderer::Renderer():
 	pps(*this),
 	bs(*this),
 	width(640),
-	height(480)
+	height(480),
+	sceneDrawer(*this)
 {}
 
 
@@ -92,278 +93,6 @@ void Renderer::drawQuad()
 }
 
 
-//======================================================================================================================
-// setupShaderProg                                                                                                     =
-//======================================================================================================================
-void Renderer::setupShaderProg(const Material& mtl, const ModelNode& modelNode, const Camera& cam) const
-{
-	mtl.getShaderProg().bind();
-	uint textureUnit = 0;
-
-	//
-	// FFP stuff
-	//
-	if(mtl.isBlendingEnabled())
-	{
-		glEnable(GL_BLEND);
-		//glDisable(GL_BLEND);
-		glBlendFunc(mtl.getBlendingSfactor(), mtl.getBlendingDfactor());
-	}
-	else
-	{
-		glDisable(GL_BLEND);
-	}
-
-
-	if(mtl.isDepthTestingEnabled())
-	{
-		glEnable(GL_DEPTH_TEST);
-	}
-	else
-	{
-		glDisable(GL_DEPTH_TEST);
-	}
-
-	if(mtl.isWireframeEnabled())
-	{
-		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-	}
-	else
-	{
-		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-	}
-
-
-	//
-	// calc needed matrices
-	//
-	Mat4 modelMat(modelNode.getWorldTransform());
-	const Mat4& projectionMat = cam.getProjectionMatrix();
-	const Mat4& viewMat = cam.getViewMatrix();
-	Mat4 modelViewMat;
-	Mat3 normalMat;
-	Mat4 modelViewProjectionMat;
-
-	// should I calculate the modelViewMat ?
-	if(mtl.getStdUniVar(Material::SUV_MODELVIEW_MAT) ||
-	   mtl.getStdUniVar(Material::SUV_MODELVIEWPROJECTION_MAT) ||
-	   mtl.getStdUniVar(Material::SUV_NORMAL_MAT))
-	{
-		modelViewMat = Mat4::combineTransformations(viewMat, modelMat);
-	}
-
-	// set matrices
-	if(mtl.getStdUniVar(Material::SUV_MODEL_MAT))
-	{
-		mtl.getStdUniVar(Material::SUV_MODEL_MAT)->setMat4(&modelMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_VIEW_MAT))
-	{
-		mtl.getStdUniVar(Material::SUV_VIEW_MAT)->setMat4(&viewMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_PROJECTION_MAT))
-	{
-		mtl.getStdUniVar(Material::SUV_PROJECTION_MAT)->setMat4(&projectionMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_MODELVIEW_MAT))
-	{
-		mtl.getStdUniVar(Material::SUV_MODELVIEW_MAT)->setMat4(&modelViewMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_VIEWPROJECTION_MAT))
-	{
-		mtl.getStdUniVar(Material::SUV_VIEWPROJECTION_MAT)->setMat4(&viewProjectionMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_NORMAL_MAT))
-	{
-		normalMat = modelViewMat.getRotationPart();
-		mtl.getStdUniVar(Material::SUV_NORMAL_MAT)->setMat3(&normalMat);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_MODELVIEWPROJECTION_MAT))
-	{
-		modelViewProjectionMat = projectionMat * modelViewMat;
-		mtl.getStdUniVar(Material::SUV_MODELVIEWPROJECTION_MAT)->setMat4(&modelViewProjectionMat);
-	}
-
-
-	//
-	// FAis
-	//
-	if(mtl.getStdUniVar(Material::SUV_MS_NORMAL_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_MS_NORMAL_FAI)->setTexture(ms.getNormalFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_MS_DIFFUSE_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_MS_DIFFUSE_FAI)->setTexture(ms.getDiffuseFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_MS_SPECULAR_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_MS_SPECULAR_FAI)->setTexture(ms.getSpecularFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_MS_DEPTH_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_MS_DEPTH_FAI)->setTexture(ms.getDepthFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_IS_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_IS_FAI)->setTexture(is.getFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_PPS_PRE_PASS_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_PPS_PRE_PASS_FAI)->setTexture(pps.getPrePassFai(), textureUnit++);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_PPS_POST_PASS_FAI))
-	{
-		mtl.getStdUniVar(Material::SUV_PPS_POST_PASS_FAI)->setTexture(pps.getPostPassFai(), textureUnit++);
-	}
-
-
-	//
-	// Other
-	//
-	if(mtl.getStdUniVar(Material::SUV_RENDERER_SIZE))
-	{
-		Vec2 v(width, height);
-		mtl.getStdUniVar(Material::SUV_RENDERER_SIZE)->setVec2(&v);
-	}
-
-	if(mtl.getStdUniVar(Material::SUV_SCENE_AMBIENT_COLOR))
-	{
-		Vec3 col(SceneSingleton::getInstance().getAmbientCol());
-		mtl.getStdUniVar(Material::SUV_SCENE_AMBIENT_COLOR)->setVec3(&col);
-	}
-
-
-	//
-	// set user defined vars
-	//
-	boost::ptr_vector<MtlUserDefinedVar>::const_iterator it = mtl.getUserDefinedVars().begin();
-	for(; it !=  mtl.getUserDefinedVars().end(); it++)
-	{
-		const MtlUserDefinedVar& udv = *it;
-
-		switch(udv.getUniVar().getGlDataType())
-		{
-			// texture or FAI
-			case GL_SAMPLER_2D:
-				if(udv.getTexture() != NULL)
-				{
-					udv.getUniVar().setTexture(*udv.getTexture(), textureUnit);
-				}
-				else
-				{
-					switch(udv.getFai())
-					{
-						case MtlUserDefinedVar::MS_DEPTH_FAI:
-							udv.getUniVar().setTexture(ms.getDepthFai(), textureUnit);
-							break;
-						case MtlUserDefinedVar::IS_FAI:
-							udv.getUniVar().setTexture(is.getFai(), textureUnit);
-							break;
-						case MtlUserDefinedVar::PPS_PRE_PASS_FAI:
-							udv.getUniVar().setTexture(pps.getPrePassFai(), textureUnit);
-							break;
-						case MtlUserDefinedVar::PPS_POST_PASS_FAI:
-							udv.getUniVar().setTexture(pps.getPostPassFai(), textureUnit);
-							break;
-						default:
-							RASSERT_THROW_EXCEPTION("WTF?");
-					}
-				}
-				++textureUnit;
-				break;
-			// float
-			case GL_FLOAT:
-				udv.getUniVar().setFloat(udv.getFloat());
-				break;
-			// vec2
-			case GL_FLOAT_VEC2:
-				udv.getUniVar().setVec2(&udv.getVec2());
-				break;
-			// vec3
-			case GL_FLOAT_VEC3:
-				udv.getUniVar().setVec3(&udv.getVec3());
-				break;
-			// vec4
-			case GL_FLOAT_VEC4:
-				udv.getUniVar().setVec4(&udv.getVec4());
-				break;
-		}
-	}
-
-	ON_GL_FAIL_THROW_EXCEPTION();
-}
-
-
-//======================================================================================================================
-// renderModelNode                                                                                                     =
-//======================================================================================================================
-void Renderer::renderModelNode(const ModelNode& modelNode, const Camera& cam, ModelNodeRenderType type) const
-{
-	boost::ptr_vector<ModelNodePatch>::const_iterator it = modelNode.getModelNodePatches().begin();
-	for(; it != modelNode.getModelNodePatches().end(); it++)
-	{
-		const ModelNodePatch& modelNodePatch = *it;
-
-		if((type == MNRT_MS && modelNodePatch.getCpMtl().renderInBlendingStage()) ||
-		   (type == MNRT_BS && !modelNodePatch.getCpMtl().renderInBlendingStage()) ||
-		   (type == MNRT_DP && modelNodePatch.getDpMtl().renderInBlendingStage()))
-		{
-			continue;
-		}
-
-		const Material* mtl;
-		const Vao* vao;
-		if(type == MNRT_MS || type == MNRT_BS)
-		{
-			mtl = &modelNodePatch.getCpMtl();
-			vao = &modelNodePatch.getCpVao();
-		}
-		else
-		{
-			mtl = &modelNodePatch.getDpMtl();
-			vao = &modelNodePatch.getDpVao();
-		}
-
-		// Shader
-		setupShaderProg(*mtl, modelNode, cam);
-
-		vao->bind();
-		glDrawElements(GL_TRIANGLES, modelNodePatch.getModelPatchRsrc().getMesh().getVertIdsNum(), GL_UNSIGNED_SHORT, 0);
-		vao->unbind();
-	}
-}
-
-
-//======================================================================================================================
-// renderAllModelNodes                                                                                                 =
-//======================================================================================================================
-void Renderer::renderAllModelNodes(const Camera& cam, ModelNodeRenderType type) const
-{
-	Scene::Types<ModelNode>::ConstIterator it = SceneSingleton::getInstance().getModelNodes().begin();
-	for(; it != SceneSingleton::getInstance().getModelNodes().end(); ++it)
-	{
-		const ModelNode& md = *(*it);
-		renderModelNode(md, cam, type);
-	}
-
-	// the rendering above fucks the polygon mode
-	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-}
-
-
 //======================================================================================================================
 // unproject                                                                                                           =
 //======================================================================================================================

+ 3 - 15
src/Renderer/Renderer.h

@@ -15,6 +15,7 @@
 #include "Bs.h"
 #include "Dbg.h"
 #include "GlException.h"
+#include "SceneDrawer.h"
 
 
 class Camera;
@@ -52,6 +53,7 @@ class Renderer
 		uint getFramesNum() const {return framesNum;}
 		GETTER_R(Mat4, viewProjectionMat, getViewProjectionMat);
 		const Camera& getCamera() const {return *cam;}
+		GETTER_R(SceneDrawer, sceneDrawer, getSceneDrawer)
 		/// @}
 
 		/// Init the renderer given an initialization class
@@ -84,21 +86,6 @@ class Renderer
 		/// OpenGL wrapper
 		static void setViewport(uint x, uint y, uint w, uint h) {glViewport(x, y, w, h);}
 
-		/// This function:
-		/// - binds the shader program
-		/// - loads the uniforms
-		/// - sets the GL state
-		/// @param mtl The material containing the shader program and the locations
-		/// @param modelNode Needed for some matrices (model) and the bone stuff (rotations & translations)
-		/// @param cam Needed for some matrices (view & projection)
-		void setupShaderProg(const class Material& mtl, const ModelNode& modelNode, const Camera& cam) const;
-
-		/// Render ModelNode. The method sets up the shader and renders the geometry
-		void renderModelNode(const ModelNode& modelNode, const Camera& cam, ModelNodeRenderType type) const;
-
-		/// Render all ModelNodes
-		void renderAllModelNodes(const Camera& cam, ModelNodeRenderType type) const;
-
 		/// Draws a quad. Actually it draws 2 triangles because OpenGL will no longer support quads
 		/// @param vertCoordsAttribLoc The attribute location of the vertex positions
 		void drawQuad();
@@ -120,6 +107,7 @@ class Renderer
 		float aspectRatio; ///< Just a precalculated value
 		const Camera* cam; ///< Current camera
 		static int maxColorAtachments; ///< Max color attachments an FBO can accept
+		SceneDrawer sceneDrawer;
 
 	//====================================================================================================================
 	// Protected                                                                                                         =

+ 2 - 1
src/Renderer/SceneDrawer.cpp

@@ -228,7 +228,8 @@ void SceneDrawer::setupShaderProg(const Material& mtl, const Transform& nodeWorl
 //======================================================================================================================
 // renderRenderableNode                                                                                                =
 //======================================================================================================================
-void SceneDrawer::renderRenderableNode(const RenderableNode& renderable, const Camera& cam, RenderingPassType rtype)
+void SceneDrawer::renderRenderableNode(const RenderableNode& renderable, const Camera& cam,
+                                       RenderingPassType rtype) const
 {
 	const Material* mtl;
 	const Vao* vao;

+ 1 - 1
src/Renderer/SceneDrawer.h

@@ -23,7 +23,7 @@ class SceneDrawer
 		/// The one and only contructor
 		SceneDrawer(const Renderer& r_): r(r_) {}
 
-		void renderRenderableNode(const RenderableNode& renderable, const Camera& cam, RenderingPassType rtype);
+		void renderRenderableNode(const RenderableNode& renderable, const Camera& cam, RenderingPassType rtype) const;
 
 	private:
 		const Renderer& r; ///< Keep it here cause the class wants a few stuff from it

+ 6 - 2
src/Renderer/Sm.cpp

@@ -1,3 +1,4 @@
+#include <boost/foreach.hpp>
 #include "Sm.h"
 #include "Renderer.h"
 #include "App.h"
@@ -68,7 +69,7 @@ void Sm::init(const RendererInitializer& initializer)
 //======================================================================================================================
 // run                                                                                                                 =
 //======================================================================================================================
-void Sm::run(const Camera& cam)
+void Sm::run(const Camera& cam, const VisibilityTester::Types<const RenderableNode*>::Container renderables)
 {
 	if(!enabled)
 	{
@@ -92,7 +93,10 @@ void Sm::run(const Camera& cam)
 	glEnable(GL_POLYGON_OFFSET_FILL);
 
 	// render all
-	r.renderAllModelNodes(cam, Renderer::MNRT_DP);
+	BOOST_FOREACH(const RenderableNode* node, renderables)
+	{
+		r.getSceneDrawer().renderRenderableNode(*node, cam, SceneDrawer::RPT_DEPTH);
+	}
 
 	// restore GL
 	glDisable(GL_POLYGON_OFFSET_FILL);

+ 2 - 1
src/Renderer/Sm.h

@@ -5,6 +5,7 @@
 #include "Fbo.h"
 #include "Texture.h"
 #include "Properties.h"
+#include "VisibilityTester.h"
 
 
 class Camera;
@@ -27,7 +28,7 @@ class Sm: private RenderingPass
 
 		/// Render the scene only with depth and store the result in the shadowMap
 		/// @param[in] cam The light camera
-		void run(const Camera& cam);
+		void run(const Camera& cam, const VisibilityTester::Types<const RenderableNode*>::Container renderables);
 
 	private:
 		Fbo fbo; ///< Illumination stage shadowmapping FBO

+ 3 - 3
src/Resources/Helpers/Image.cpp

@@ -1,6 +1,6 @@
 #include <png.h>
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp> // for to_lower
+#include <boost/filesystem.hpp> // For file extensions
+#include <boost/algorithm/string.hpp> // For to_lower
 #include <fstream>
 #include "Image.h"
 #include "Exception.h"
@@ -285,7 +285,7 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 	// Init io
 	//
 	png_init_io(pngPtr, file);
-	png_set_sig_bytes(pngPtr, PNG_SIG_SIZE); // PNG lib knows that we allready have read the header
+	png_set_sig_bytes(pngPtr, PNG_SIG_SIZE); // PNG lib knows that we already have read the header
 
 	//
 	// Read info and make conversions

+ 13 - 7
src/Resources/Helpers/Image.h

@@ -2,7 +2,6 @@
 #define IMAGE_H
 
 #include "Vec.h"
-#include "Properties.h"
 #include "StdTypes.h"
 
 
@@ -19,19 +18,26 @@ class Image
 			CT_RGBA /// RGB plus alpha
 		};
 
-	PROPERTY_R(uint, width, getWidth) ///< Image width
-	PROPERTY_R(uint, height, getHeight) ///< Image height
-	PROPERTY_R(ColorType, type, getType) ///< Image color type
-	PROPERTY_R(Vec<uchar>, data, getData) ///< Image data
-
-	public:
 		/// Load an image
 		/// @param[in] filename The image file to load
 		/// @exception Exception
 		Image(const char* filename) {load(filename);}
 		~Image() {}
 
+		/// @name Accessors
+		/// @{
+		uint getWidth() const {return width;}
+		uint getHeight() const {return height;}
+		ColorType getColorType() const {return type;}
+		const Vec<uchar>& getData() const {return data;}
+		/// @}
+
 	private:
+		uint width; ///< Image width
+		uint height; ///< Image height
+		ColorType type; ///< Image color type
+		Vec<uchar> data; ///< Image data
+
 		/// @name TGA headers
 		/// @{
 		static uchar tgaHeaderUncompressed[12];

+ 2 - 0
src/Resources/Mesh.cpp

@@ -27,6 +27,8 @@ void Mesh::load(const char* filename)
 		}
 
 		createVbos(meshData);
+
+		boundingShape = Sphere((const float*)(&meshData.getVertCoords()[0]), 0, meshData.getVertCoords().size());
 	}
 	catch(std::exception& e)
 	{

+ 9 - 6
src/Resources/Mesh.h

@@ -5,7 +5,7 @@
 #include "Math.h"
 #include "RsrcPtr.h"
 #include "Vbo.h"
-#include "Properties.h"
+#include "Sphere.h"
 
 
 class MeshData;
@@ -27,22 +27,23 @@ class Mesh
 			VBOS_NUM
 		};
 
-	PROPERTY_R(uint, vertIdsNum, getVertIdsNum)
-
-	public:
 		/// Default constructor
 		Mesh() {}
 
 		/// Does nothing
 		~Mesh() {}
 
-		/// Accessor
+		/// @name Accessors
+		/// @{
 		const Vbo& getVbo(Vbos id) const {return vbos[id];}
+		uint getVertIdsNum() const {return vertIdsNum;}
+		const Sphere& getBoundingShape() const {return boundingShape;}
+		/// @}
 
 		/// Implements @ref Resource::load
 		void load(const char* filename);
 
-		/// @name Ask for data
+		/// @name Ask for geometry properties
 		/// @{
 		bool hasTexCoords() const {return vbos[VBO_TEX_COORDS].isCreated();}
 		bool hasVertWeights() const {return vbos[VBO_VERT_WEIGHTS].isCreated();}
@@ -51,6 +52,8 @@ class Mesh
 
 	private:
 		boost::array<Vbo, VBOS_NUM> vbos; ///< The vertex buffer objects
+		uint vertIdsNum; ///< The number of vertex IDs
+		Sphere boundingShape;
 
 		/// Create the VBOs
 		void createVbos(const MeshData& meshData);

+ 14 - 3
src/Resources/Model.cpp

@@ -2,6 +2,8 @@
 #include <boost/property_tree/xml_parser.hpp>
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/assign.hpp>
+#include <boost/range/iterator_range.hpp>
 #include "Model.h"
 #include "Material.h"
 #include "Mesh.h"
@@ -34,9 +36,18 @@ void Model::load(const char* filename)
   		const std::string& material = v.second.get<std::string>("material");
   		const std::string& dpMaterial = v.second.get<std::string>("dpMaterial");
 
-  		ModelPatch* sub = new ModelPatch();
-  		modelPatches.push_back(sub);
-  		sub->load(mesh.c_str(), material.c_str(), dpMaterial.c_str());
+  		ModelPatch* patch = new ModelPatch();
+  		modelPatches.push_back(patch);
+  		patch->load(mesh.c_str(), material.c_str(), dpMaterial.c_str());
+
+  		boundingShape = boundingShape.getCompoundSphere(patch->getMesh().getBoundingShape());
+  	}
+
+  	// Bounding volume
+  	boundingShape = modelPatches[0].getMesh().getBoundingShape();
+  	BOOST_FOREACH(const ModelPatch& patch, boost::make_iterator_range(modelPatches.begin() + 1, modelPatches.end()))
+  	{
+  		boundingShape = boundingShape.getCompoundSphere(patch.getMesh().getBoundingShape());
   	}
 	}
 	catch(std::exception& e)

+ 3 - 0
src/Resources/Model.h

@@ -5,6 +5,7 @@
 #include "RsrcPtr.h"
 #include "Vao.h"
 #include "ModelPatch.h"
+#include "Sphere.h"
 
 
 /// Model is an entity that acts as a container for other resources. Models are all the non static objects in a map.
@@ -38,10 +39,12 @@ class Model
 		/// @name Accessors
 		/// @{
 		const boost::ptr_vector<ModelPatch>& getModelPatches() const {return modelPatches;}
+		const Sphere& getBoundingShape() const {return boundingShape;}
 		/// @}
 
 	private:
 		boost::ptr_vector<ModelPatch> modelPatches; ///< The vector of ModelPatch
+		Sphere boundingShape;
 };
 
 

+ 2 - 2
src/Resources/ModelPatch.cpp

@@ -59,7 +59,7 @@ void ModelPatch::doMeshAndMtlSanityChecks(const Mesh& mesh, const Material& mtl)
 			throw EXCEPTION("Texture coords");
 		}
 
-		// normals & tangents
+		// Normals
 		if(mtl.getStdAttribVar(Material::SAV_NORMAL) != NULL && !mesh.hasNormalsAndTangents())
 		{
 			throw EXCEPTION("Normals");
@@ -73,6 +73,6 @@ void ModelPatch::doMeshAndMtlSanityChecks(const Mesh& mesh, const Material& mtl)
 	}
 	catch(std::exception& e)
 	{
-		throw EXCEPTION("Mesh and material are incompatible");
+		throw EXCEPTION("Mesh and material are incompatible: " + e.what());
 	}
 }

+ 1 - 1
src/Resources/Texture.cpp

@@ -124,7 +124,7 @@ void Texture::load(const char* filename)
 		int internalFormat;
 		int format;
 		int type;
-		switch(img.getType())
+		switch(img.getColorType())
 		{
 			case Image::CT_R:
 				internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;

+ 20 - 29
src/Scene/Camera.h

@@ -1,6 +1,7 @@
 #ifndef CAMERA_H
 #define CAMERA_H
 
+#include <boost/array.hpp>
 #include "Collision.h"
 #include "SceneNode.h"
 
@@ -19,30 +20,33 @@ class Camera: public SceneNode
 			FP_FAR
 		};
 
-	public:
-		// constructors and destuctors
-		Camera(float fovx_, float fovy_, float znear_, float zfar_, bool compoundFlag, SceneNode* parent = NULL);
 		Camera(bool compoundFlag, SceneNode* parent): SceneNode(SNT_CAMERA, compoundFlag, parent) {}
 		~Camera() {}
 
 		/// @name Accessors
 		//// @{
-		void setFovX (float fovx_)  { fovX=fovx_; calcProjectionMatrix(); calcLSpaceFrustumPlanes(); }
-		void setFovY (float fovy_)  { fovY=fovy_; calcProjectionMatrix(); calcLSpaceFrustumPlanes(); }
-		void setZNear(float znear_) { zNear=znear_; calcProjectionMatrix(); calcLSpaceFrustumPlanes(); }
-		void setZFar (float zfar_)  { zFar=zfar_; calcProjectionMatrix(); calcLSpaceFrustumPlanes(); }
+		void setFovX (float fovx_)  {fovX=fovx_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
+		void setFovY (float fovy_)  {fovY=fovy_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
+		void setZNear(float znear_) {zNear=znear_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
+		void setZFar (float zfar_)  {zFar=zfar_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
 		void setAll(float fovx_, float fovy_, float znear_, float zfar_);
-		float getFovX () const { return fovX; }
-		float getFovY () const { return fovY; }
-		float getZNear() const { return zNear; }
-		float getZFar () const { return zFar; }
-		const Mat4& getProjectionMatrix() const { return projectionMat; }
-		const Mat4& getViewMatrix() const { return viewMat; }
-		const Mat4& getInvProjectionMatrix() const { return invProjectionMat; } ///< See the declaration of invProjectionMat for info
+		float getFovX() const {return fovX;}
+		float getFovY() const {return fovY;}
+		float getZNear() const {return zNear;}
+		float getZFar() const {return zFar;}
+		const Mat4& getProjectionMatrix() const {return projectionMat;}
+		const Mat4& getViewMatrix() const {return viewMat;}
+		const Mat4& getInvProjectionMatrix() const {return invProjectionMat;} ///< See the declaration of invProjectionMat for info
 		//// @}
 
 		void lookAtPoint(const Vec3& point);
+
+		/// This does:
+		/// - Update view matrix
+		/// - Update frustum planes
 		void updateTrf();
+
+		/// Do nothing
 		void init(const char*) {}
 
 		/// @name Frustum checks
@@ -68,8 +72,8 @@ class Camera: public SceneNode
 
 		/// @name The frustum planes in local and world space
 		/// @{
-		Plane lspaceFrustumPlanes[6];
-		Plane wspaceFrustumPlanes[6];
+		boost::array<Plane, 6> lspaceFrustumPlanes;
+		boost::array<Plane, 6> wspaceFrustumPlanes;
 		/// @}
 
 		/// @name Matrices
@@ -91,17 +95,4 @@ class Camera: public SceneNode
 };
 
 
-inline Camera::Camera(float fovx_, float fovy_, float znear_, float zfar_, bool compoundFlag, SceneNode* parent):
-	SceneNode(SNT_CAMERA, compoundFlag, parent),
-	fovX(fovx_),
-	fovY(fovy_),
-	zNear(znear_),
-	zFar(zfar_)
-{
-	calcLSpaceFrustumPlanes();
-	updateWSpaceFrustumPlanes();
-	calcProjectionMatrix();
-}
-
-
 #endif

+ 11 - 1
src/Scene/ModelNode.cpp

@@ -12,6 +12,16 @@ void ModelNode::init(const char* filename)
 
 	for(uint i = 0; i < model->getModelPatches().size(); i++)
 	{
-		patches.push_back(new ModelPatchNode(*this, model->getModelPatches()[i], this));
+		patches.push_back(new ModelPatchNode(model->getModelPatches()[i], this));
 	}
 }
+
+
+//======================================================================================================================
+// updateTrf                                                                                                           =
+//======================================================================================================================
+void ModelNode::updateTrf()
+{
+	// Update bounding shape
+	boundingShapeWSpace = model->getBoundingShape().getTransformed(worldTransform);
+}

+ 7 - 0
src/Scene/ModelNode.h

@@ -7,6 +7,7 @@
 #include "Properties.h"
 #include "ModelPatchNode.h"
 #include "Vec.h"
+#include "Sphere.h"
 
 
 class Model;
@@ -21,12 +22,17 @@ class ModelNode: public SceneNode
 		/// @name Accessors
 		/// @{
 		const Model& getModel() const {return *model;}
+		GETTER_R(Vec<ModelPatchNode*>, patches, getModelPatchNodes)
+		GETTER_R(Sphere, boundingShapeWSpace, getBoundingShapeWSpace)
 		/// @}
 
 		/// Initialize the node
 		/// - Load the resource
 		void init(const char* filename);
 
+		/// Update the bounding shape
+		void updateTrf();
+
 		/// @name Accessors
 		/// @{
 		const Vec<ModelPatchNode*>& getModelPatchNodees() const {return patches;}
@@ -35,6 +41,7 @@ class ModelNode: public SceneNode
 	private:
 		RsrcPtr<Model> model;
 		Vec<ModelPatchNode*> patches;
+		Sphere boundingShapeWSpace;
 };
 
 

+ 6 - 6
src/Scene/ModelPatchNode.cpp

@@ -10,19 +10,19 @@
 //======================================================================================================================
 // Constructor                                                                                                         =
 //======================================================================================================================
-ModelPatchNode::ModelPatchNode(const ModelNode& modelNode, const ModelPatch& modelPatch_, ModelNode* parent):
-	RenderableNode(parent),
-	modelPatchRsrc(modelPatch_)
+ModelPatchNode::ModelPatchNode(const ModelPatch& modelPatch_, ModelNode* parent):
+	RenderableNode(modelPatch_.getMesh().getBoundingShape(), parent),
+	rsrc(modelPatch_)
 {
 	boost::array<const Vbo*, Mesh::VBOS_NUM> vboArr;
 
 	for(uint i = 0; i < Mesh::VBOS_NUM; i++)
 	{
-		vboArr[i] = &modelPatchRsrc.getMesh().getVbo((Mesh::Vbos)i);
+		vboArr[i] = &rsrc.getMesh().getVbo((Mesh::Vbos)i);
 	}
 
-	createVao(modelPatchRsrc.getCpMtl(), vboArr, cpVao);
-	createVao(modelPatchRsrc.getDpMtl(), vboArr, dpVao);
+	createVao(rsrc.getCpMtl(), vboArr, cpVao);
+	createVao(rsrc.getDpMtl(), vboArr, dpVao);
 }
 
 

+ 2 - 1
src/Scene/ModelPatchNode.h

@@ -18,8 +18,9 @@ class ModelNode;
 class ModelPatchNode: public RenderableNode
 {
 	public:
-		ModelPatchNode(const ModelNode& modelNode, const ModelPatch& modelPatch, ModelNode* parent);
+		ModelPatchNode(const ModelPatch& modelPatch, ModelNode* parent);
 
+		/// Do nothing
 		void init(const char*) {}
 
 		/// @name Accessors

+ 19 - 0
src/Scene/RenderableNode.cpp

@@ -0,0 +1,19 @@
+#include "RenderableNode.h"
+
+
+//======================================================================================================================
+// Constructor                                                                                                         =
+//======================================================================================================================
+RenderableNode::RenderableNode(const Sphere& boundingShapeLSpace_, SceneNode* parent):
+	SceneNode(SNT_RENDERABLE, false, parent),
+	boundingShapeLSpace(boundingShapeLSpace_)
+{}
+
+
+//======================================================================================================================
+// updateTrf                                                                                                           =
+//======================================================================================================================
+void RenderableNode::updateTrf()
+{
+	boundingShapeWSpace = boundingShapeLSpace.getTransformed(getWorldTransform());
+}

+ 10 - 1
src/Scene/RenderableNode.h

@@ -2,6 +2,7 @@
 #define RENDERABLE_NODE_H
 
 #include "SceneNode.h"
+#include "Sphere.h"
 
 
 class Vao;
@@ -12,13 +13,21 @@ class Material;
 class RenderableNode: public SceneNode
 {
 	public:
-		RenderableNode(SceneNode* parent): SceneNode(SNT_RENDERABLE, false, parent) {}
+		RenderableNode(const Sphere& boundingShapeLSpace, SceneNode* parent);
 
 		virtual const Vao& getCpVao() const = 0; ///< Get color pass VAO
 		virtual const Vao& getDpVao() const = 0; ///< Get depth pass VAO
 		virtual uint getVertIdsNum() const = 0;  ///< Get vert ids number for rendering
 		virtual const Material& getCpMtl() const = 0;  ///< Get color pass material
 		virtual const Material& getDpMtl() const = 0;  ///< Get depth pass material
+		const Sphere& getBoundingShapeWSpace() const {return boundingShapeWSpace;}
+
+		/// Update the bounding shape
+		virtual void updateTrf();
+
+	private:
+		Sphere boundingShapeLSpace;
+		Sphere boundingShapeWSpace;
 };
 
 

+ 3 - 0
src/Scene/Scene.cpp

@@ -7,6 +7,7 @@
 #include "Material.h"
 #include "ParticleEmitter.h"
 #include "ModelNode.h"
+#include "VisibilityTester.h"
 
 
 //======================================================================================================================
@@ -18,6 +19,8 @@ Scene::Scene()
 	//sunPos = Vec3(0.0, 1.0, -1.0) * 50.0;
 
 	physics.reset(new Physics);
+
+	visibilityTester.reset(new VisibilityTester(*this));
 }
 
 

+ 5 - 1
src/Scene/Scene.h

@@ -6,6 +6,7 @@
 #include "Exception.h"
 #include "Properties.h"
 #include "Singleton.h"
+#include "VisibilityTester.h"
 
 
 class SceneNode;
@@ -32,7 +33,7 @@ class Scene
 		};
 
 		Scene();
-		~Scene() throw() {}
+		~Scene() {}
 
 		void registerNode(SceneNode* node); ///< Put a node in the appropriate containers
 		void unregisterNode(SceneNode* node);
@@ -41,12 +42,14 @@ class Scene
 
 		void updateAllWorldStuff();
 		void updateAllControllers();
+		void doVisibilityTests(const Camera& cam) {visibilityTester->test(cam);}
 
 		/// @name Accessors
 		/// @{
 		GETTER_SETTER(Vec3, ambientCol, getAmbientCol, setAmbientCol)
 		Physics& getPhysics() {return *physics;}
 		const Physics& getPhysics() const {return *physics;}
+		const VisibilityTester& getVisibilityTester() const {return *visibilityTester;}
 
 		GETTER_RW(Types<SceneNode>::Container, nodes, getAllNodes)
 		GETTER_RW(Types<Light>::Container, lights, getLights)
@@ -71,6 +74,7 @@ class Scene
 
 		Vec3 ambientCol; ///< The global ambient color
 		std::auto_ptr<Physics> physics; ///< Connection with Bullet wrapper
+		std::auto_ptr<VisibilityTester> visibilityTester;
 
 		/// Adds a node in a container
 		template<typename ContainerType, typename Type>

+ 3 - 1
src/Scene/SceneNode.h

@@ -57,9 +57,11 @@ class SceneNode: private Object
 		void moveLocalZ(float distance);
 		/// @}
 
-	private:
+	protected:
 		Transform localTransform; ///< The transformation in local space
 		Transform worldTransform; ///< The transformation in world space (local combined with parent's transformation)
+
+	private:
 		SceneNodeType type;
 		bool compoundFlag; ///< This means that the children will inherit the world transform of this node
 

+ 1 - 0
src/Scene/SkinNode.cpp

@@ -1,4 +1,5 @@
 #include "SkinNode.h"
+#include "Skin.h"
 
 
 //======================================================================================================================

+ 80 - 50
src/Scene/VisibilityTester.cpp

@@ -1,3 +1,4 @@
+#include <boost/foreach.hpp>
 #include "VisibilityTester.h"
 #include "Scene.h"
 #include "ModelNode.h"
@@ -9,11 +10,12 @@
 
 
 //======================================================================================================================
-// CmpLength::operator()                                                                                               =
+// CmpDistanceFromOrigin::operator()                                                                                   =
 //======================================================================================================================
-inline bool VisibilityTester::CmpLength::operator()(const RenderableNode* a, const RenderableNode* b) const
+bool VisibilityTester::CmpDistanceFromOrigin::operator()(const RenderableNode* a, const RenderableNode* b) const
 {
-	return (a->getWorldTransform().origin - o).getLengthSquared() < (b->getWorldTransform().origin - o).getLengthSquared();
+	return (a->getWorldTransform().origin - o).getLengthSquared() <
+	       (b->getWorldTransform().origin - o).getLengthSquared();
 }
 
 
@@ -39,19 +41,51 @@ void VisibilityTester::test(const Camera& cam)
 	spotLights.clear();
 
 	//
-	// Collect the lights
+	// Collect the renderables
 	//
-	Scene::Types<Light>::ConstIterator itl = scene.getLights().begin();
-	for(; itl != scene.getLights().end(); itl++)
+	BOOST_FOREACH(const ModelNode* node, scene.getModelNodes())
 	{
-		const Light& light = *(*itl);
+		// Skip if the ModeNode is not visible
+		if(!test(*node, cam))
+		{
+			continue;
+		}
 
-		// Point
-		switch(light.getType())
+		// If not test every patch individually
+		BOOST_FOREACH(const ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
 		{
+			// Test if visible by main camera
+			if(test(*modelPatchNode, cam))
+			{
+				if(modelPatchNode->getCpMtl().isBlendingEnabled())
+				{
+					bsRenderables.push_back(modelPatchNode);
+				}
+				else
+				{
+					msRenderables.push_back(modelPatchNode);
+				}
+			}
+		}
+	}
+
+	//
+	// Sort the renderables from closest to the camera to the farthest
+	//
+	std::sort(msRenderables.begin(), msRenderables.end(), CmpDistanceFromOrigin(cam.getWorldTransform().origin));
+	std::sort(bsRenderables.begin(), bsRenderables.end(), CmpDistanceFromOrigin(cam.getWorldTransform().origin));
+
+	//
+	// Collect the lights
+	//
+	BOOST_FOREACH(const Light* light, scene.getLights())
+	{
+		switch(light->getType())
+		{
+			// Point
 			case Light::LT_POINT:
 			{
-				const PointLight& pointl = static_cast<const PointLight&>(light);
+				const PointLight& pointl = static_cast<const PointLight&>(*light);
 
 				Sphere sphere(pointl.getWorldTransform().origin, pointl.getRadius());
 				if(cam.insideFrustum(sphere))
@@ -64,7 +98,7 @@ void VisibilityTester::test(const Camera& cam)
 			// Spot
 			case Light::LT_SPOT:
 			{
-				const SpotLight& spotl = static_cast<const SpotLight&>(light);
+				const SpotLight& spotl = static_cast<const SpotLight&>(*light);
 
 				if(cam.insideFrustum(spotl.getCamera()))
 				{
@@ -73,59 +107,55 @@ void VisibilityTester::test(const Camera& cam)
 				}
 				break;
 			}
-		}
-	}
+		} // end switch
+	} // end for all lights
 
 	//
-	// Collect the renderables
+	// For all the spot lights get the visible renderables
 	//
-	Scene::Types<ModelNode>::ConstIterator it = scene.getModelNodes().begin();
-	for(; it != scene.getModelNodes().end(); it++)
+	BOOST_FOREACH(VisibleLight<SpotLight>& sl, spotLights)
 	{
-		boost::ptr_vector<ModelPatchNode>::const_iterator it2 = (*it)->getModelPatchNodees().begin();
-		for(; it2 != (*it)->getModelPatchNodees().end(); it2++)
+		// Skip if the light doesnt cast shadow
+		if(!sl.light->castsShadow())
 		{
-			const ModelPatchNode& modelNodePatch = *it2;
+			continue;
+		}
 
-			// First check if its rendered by a light
-			Types<VisibleLight<SpotLight> >::Iterator itsl = spotLights.begin();
-			for(; itsl != spotLights.end(); itsl++)
+		BOOST_FOREACH(const ModelNode* node, scene.getModelNodes())
+		{
+			// Skip if the ModeNode is not visible
+			if(!test(*node, sl.light->getCamera()))
 			{
-				const SpotLight& spotLight = *(itsl->light);
-				if(test(modelNodePatch, spotLight.getCamera()))
-				{
-					itsl->renderables.push_back(&modelNodePatch);
-				}
+				continue;
 			}
 
-
-			/// @todo Perform real tests
-			if(test(modelNodePatch, cam))
+			// If not test every patch individually
+			BOOST_FOREACH(const ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
 			{
-				if(modelNodePatch.getCpMtl().isBlendingEnabled())
+				// Skip if doesnt cast shadow
+				if(!modelPatchNode->getCpMtl().isShadowCaster())
 				{
-					bsRenderables.push_back(&modelNodePatch);
+					continue;
 				}
-				else
+
+				if(test(*modelPatchNode, sl.light->getCamera()))
 				{
-					msRenderables.push_back(&modelNodePatch);
+					sl.renderables.push_back(modelPatchNode);
 				}
-			}
-		}
-	}
+			} // end for all patches
+		} // end for all model nodes
 
-	//
-	// 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));
+		std::sort(sl.renderables.begin(), sl.renderables.end(),
+		          CmpDistanceFromOrigin(sl.light->getWorldTransform().origin));
+	} // end for all spot lights
+}
 
-	//
-	// Short the light's renderables
-	//
-	Types<VisibleLight<SpotLight> >::Iterator itsl = spotLights.begin();
-	for(; itsl != spotLights.end(); itsl++)
-	{
-		std::sort(itsl->renderables.begin(), itsl->renderables.end(), CmpLength(itsl->light->getWorldTransform().origin));
-	}
+
+//======================================================================================================================
+// test                                                                                                                =
+//======================================================================================================================
+template<typename Type>
+bool VisibilityTester::test(const Type& tested, const Camera& cam)
+{
+	return cam.insideFrustum(tested.getBoundingShapeWSpace());
 }

+ 13 - 4
src/Scene/VisibilityTester.h

@@ -56,6 +56,11 @@ class VisibilityTester
 		GETTER_R(Types<VisibleLight<SpotLight> >::Container, spotLights, getSpotLights)
 		/// @}
 
+		/// This method:
+		/// - Gets the visible renderable nodes
+		/// - Sort them from the closest to the farthest
+		/// - Get the visible lights
+		/// - For every spot light that casts shadow get the visible renderables
 		void test(const Camera& cam);
 
 	//====================================================================================================================
@@ -63,22 +68,26 @@ class VisibilityTester
 	//====================================================================================================================
 	private:
 		/// Used in sorting. Compare the length of 2 nodes from the camera
-		struct CmpLength
+		struct CmpDistanceFromOrigin
 		{
 			Vec3 o; ///< The camera origin
-			CmpLength(Vec3 o_): o(o_) {}
+			CmpDistanceFromOrigin(Vec3 o_): o(o_) {}
 			bool operator()(const RenderableNode* a, const RenderableNode* b) const;
 		};
 
 		const Scene& scene; ///< Know your father
 
+		/// @name Containers
+		/// @{
 		Types<const RenderableNode*>::Container msRenderables;
 		Types<const RenderableNode*>::Container bsRenderables;
 		Types<VisibleLight<PointLight> >::Container pointLights;
 		Types<VisibleLight<SpotLight> >::Container spotLights;
+		/// @}
 
-		/// @todo write some real code
-		static bool test(const RenderableNode& /*renderable*/, const Camera& /*cam*/) {return true;}
+		/// Test a node against the camera frustum
+		template<typename Type>
+		static bool test(const Type& tested, const Camera& cam);
 };
 
 

+ 2 - 4
src/Util/Exception.cpp

@@ -1,5 +1,6 @@
 #include <cstdio>
 #include <cstring>
+#include <boost/lexical_cast.hpp>
 #include "Exception.h"
 
 
@@ -8,8 +9,5 @@
 //======================================================================================================================
 void Exception::init(const char* err_, const char* file, int line, const char* func)
 {
-	char tmpStr[1024];
-	sprintf(tmpStr, "\n(%s:%d %s) %s", file, line, func, err_);
-	//sprintf(tmpStr, "%s", err_);
-	err = tmpStr;
+	err = std::string("\n(") + file + ":" + boost::lexical_cast<std::string>(line) + " " + func + ") " + err_;
 }

+ 1 - 1
src/Util/Exception.h

@@ -5,7 +5,7 @@
 #include <string>
 
 
-/// Custom exception that takes file, line and function that throwed it. Throw it using the EXCEPTION macro
+/// Custom exception that takes file, line and function that throw it. Throw it using the EXCEPTION macro
 class Exception: public std::exception
 {
 	public:

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác