Browse Source

Fixing bugs and optimizing so far

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
e88739cd1c

+ 4 - 5
include/anki/collision/Frustum.h

@@ -12,10 +12,8 @@ namespace anki {
 /// @addtogroup Collision
 /// @{
 
-/// Frustum collision shape
-///
-/// This shape consists from 6 planes. The planes are being used to find shapes
-/// that are inside the frustum
+/// Frustum collision shape. This shape consists from 6 planes. The planes are
+/// being used to find shapes that are inside the frustum
 class Frustum: public CollisionShape
 {
 public:
@@ -93,7 +91,8 @@ public:
 	/// Calculate the projection matrix
 	virtual Mat4 calculateProjectionMatrix() const = 0;
 
-	/// XXX
+	/// Its like transform() but but with a difference. It doesn't transform
+	/// the @a trf, it just replaces it
 	virtual void setTransform(const Transform& trf) = 0;
 
 protected:

+ 6 - 1
include/anki/renderer/Drawer.h

@@ -170,6 +170,11 @@ public:
 
 	virtual void draw(Octree& octree) const;
 
+	void setViewProjectionMatrix(const Mat4& m)
+	{
+		dbg->setViewProjectionMatrix(m);
+	}
+
 private:
 	DebugDrawer* dbg;
 
@@ -204,6 +209,6 @@ private:
 		Renderable& renderable);
 };
 
-} // namespace anki
+} // end namespace anki
 
 #endif

+ 39 - 34
include/anki/scene/Property.h

@@ -15,24 +15,32 @@
 
 namespace anki {
 
-typedef Visitable<std::string, bool, float,
-	Vec2, Vec3, Vec4, Mat3, Mat4, Transform,
-	OrthographicFrustum, PerspectiveFrustum,
-	TextureResourcePointer>
-	PropertyVisitable;
-
 // Forward
+class PropertyBase;
+
 template<typename T>
 class Property;
 
+typedef VisitableCommonBase<
+	PropertyBase, // Base
+	// Misc
+	Property<std::string>, Property<bool>, Property<float>,
+	Property<TextureResourcePointer>,
+	// Math
+	Property<Vec2>, Property<Vec3>, Property<Vec4>, Property<Mat3>,
+	Property<Mat4>, Property<Transform>,
+	// Collision
+	Property<OrthographicFrustum>, Property<PerspectiveFrustum>>
+	PropertyVisitable;
+
 /// Base class for property
-class PropertyBase: public NonCopyable
+class PropertyBase: public NonCopyable, public PropertyVisitable
 {
 public:
 	/// @name Constructors/Destructor
 	/// @{
-	PropertyBase(const char* name_, uint tid_)
-		: name(name_), tid(tid_)
+	PropertyBase(const char* name_)
+		: name(name_)
 	{}
 
 	virtual ~PropertyBase()
@@ -46,25 +54,20 @@ public:
 		return name;
 	}
 
-	uint32_t getTypeId() const
-	{
-		return tid;
-	}
-
 	/// Get the property value. Throws if the @a T is incorrect
-	template<typename T>
-	const T& getValue() const
+	template<typename TValue>
+	const TValue& getValue() const
 	{
-		checkType<Property<T> >();
-		return static_cast<const Property<T>*>(this)->getValue();
+		checkType<TValue>();
+		return static_cast<const Property<TValue>*>(this)->getValue();
 	}
 
 	/// Set the property value. Throws if the @a T is incorrect
-	template<typename T>
-	void setValue(const T& x)
+	template<typename TValue>
+	void setValue(const TValue& x)
 	{
-		checkType<Property<T> >();
-		return static_cast<Property<T>*>(this)->setValue(x);
+		checkType<TValue>();
+		return static_cast<Property<TValue>*>(this)->setValue(x);
 	}
 	/// @}
 
@@ -72,19 +75,19 @@ public:
 	template<typename TProp>
 	TProp& upCast()
 	{
-		checkType<TProp>();
+		checkType<TProp::Value>();
 		return static_cast<TProp&>(*this);
 	}
 
 private:
 	std::string name;
-	uint32_t tid; ///< Type ID
 
 	/// Runtime type checking
-	template<typename TProp>
+	template<typename TValue>
 	void checkType() const
 	{
-		if(PropertyVisitable::getVariadicTypeId<TProp> != tid)
+		if(PropertyVisitable::getVariadicTypeId<Property<TValue>>() !=
+			getVisitableTypeId())
 		{
 			throw ANKI_EXCEPTION("Types do not match: " + name);
 		}
@@ -104,8 +107,10 @@ public:
 
 	/// Read only property
 	Property(const char* name)
-		: PropertyBase(name, PropertyVisitable::getVariadicTypeId<T>())
-	{}
+		: PropertyBase(name)
+	{
+		setupVisitable(this);
+	}
 	/// @}
 
 	/// @name Accessors
@@ -136,8 +141,8 @@ public:
 
 	/// @name Constructors/Destructor
 	/// @{
-	ReadProperty(const char* name, const Value& x_)
-		: Base(name), x(x_)
+	ReadProperty(const char* name, const Value& initialValue)
+		: Base(name), x(initialValue)
 	{}
 	/// @}
 
@@ -165,8 +170,8 @@ public:
 
 	/// @name Constructors/Destructor
 	/// @{
-	ReadWriteProperty(const char* name, const Value& x_)
-		: Base(name), x(x_)
+	ReadWriteProperty(const char* name, const Value& initialValue)
+		: Base(name), x(initialValue)
 	{}
 	/// @}
 
@@ -201,8 +206,8 @@ public:
 
 	/// @name Constructors/Destructor
 	/// @{
-	ReadPointerProperty(const char* name, const Value* x)
-		: Base(name), ptr(x)
+	ReadPointerProperty(const char* name, const Value* ptr_)
+		: Base(name), ptr(ptr_)
 	{}
 	/// @}
 

+ 30 - 13
include/anki/scene/Renderable.h

@@ -15,7 +15,7 @@ class Transform;
 /// @addtogroup Scene
 /// @{
 
-/// XXX
+/// Material variable property. Its a layer on top of material variables
 template<typename T>
 class MaterialVariableProperty: public ReadCowPointerProperty<T>
 {
@@ -25,34 +25,44 @@ public:
 
 	/// @name Constructors/Destructor
 	/// @{
-	MaterialVariableProperty(const char* name, const Value* x, bool buildin_)
-		: Base(name, x), buildin(buildin_)
+	MaterialVariableProperty(const char* name, const Value* x,
+		const MaterialVariable* mvar_)
+		: Base(name, x), mvar(mvar_)
 	{}
 	/// @}
 
 	/// @name Accessors
 	/// @{
-	bool isBuildIn() const
+	uint32_t getBuildinId() const
 	{
-		return buildin;
+		return buildinId;
+	}
+	void setBuildinId(uint32_t id)
+	{
+		buildinId = id;
+	}
+
+	const MaterialVariable& getMaterialVariable() const
+	{
+		return *mvar;
 	}
 	/// @}
 
 private:
-	bool buildin;
+	uint32_t buildinId = 0; ///< The renderer sets it
+	const MaterialVariable* mvar = nullptr;
 };
 
 /// Renderable interface. Implemented by renderable scene nodes
 class Renderable
 {
 public:
-	typedef std::vector<PropertyBase*> Properties;
+	typedef std::vector<PropertyBase*> MaterialVariableProperties;
 
 	Renderable()
 	{}
 
-	virtual ~Renderable()
-	{}
+	virtual ~Renderable();
 
 	/// Access to VAOs
 	virtual const ModelPatchBase& getModelPatchBase() const = 0;
@@ -66,23 +76,30 @@ public:
 		return nullptr;
 	}
 
-	const Properties& getProperties() const
+	/// @name Accessors
+	/// @{
+	MaterialVariableProperties::iterator getPropertiesBegin()
 	{
-		return props;
+		return props.begin();
 	}
+	MaterialVariableProperties::iterator getPropertiesEnd()
+	{
+		return props.end();
+	}
+	/// @}
 
 protected:
 	void init(PropertyMap& pmap);
 
 private:
-	Properties props;
+	MaterialVariableProperties props;
 };
 
 
 /// @}
 
 
-} // end namespace
+} // end namespace anki
 
 
 #endif

+ 8 - 4
include/anki/scene/Scene.h

@@ -5,7 +5,6 @@
 #include "anki/scene/VisibilityTester.h"
 #include "anki/math/Math.h"
 #include "anki/util/Singleton.h"
-#include <boost/range/iterator_range.hpp>
 #include <vector>
 
 namespace anki {
@@ -22,8 +21,6 @@ public:
 		typedef std::vector<T*> Container;
 		typedef typename Container::iterator Iterator;
 		typedef typename Container::const_iterator ConstIterator;
-		typedef boost::iterator_range<Iterator> MutableRange;
-		typedef boost::iterator_range<ConstIterator> ConstRange;
 		typedef typename ConstCharPtrHashMap<T*>::Type NameToItemMap;
 	};
 
@@ -97,6 +94,12 @@ public:
 
 	void doVisibilityTests(Camera& cam);
 
+	SceneNode* findSceneNode(const char* name)
+	{
+		Types<SceneNode>::NameToItemMap::iterator it = nameToNode.find(name);
+		return (it == nameToNode.end()) ? nullptr : it->second;
+	}
+
 private:
 	Types<SceneNode>::Container nodes;
 	Types<SceneNode>::NameToItemMap nameToNode;
@@ -119,7 +122,8 @@ private:
 	{
 		if(d.find(ptr->getName().c_str()) != d.end())
 		{
-			throw ANKI_EXCEPTION("Item already exists: " + ptr->getName());
+			throw ANKI_EXCEPTION("Item with same name already exists: "
+				+ ptr->getName());
 		}
 
 		d[ptr->getName().c_str()] = ptr;

+ 12 - 7
include/anki/scene/VisibilityTester.h

@@ -2,7 +2,6 @@
 #define ANKI_SCENE_VISIBILITY_TESTER_H
 
 #include <vector>
-#include <boost/range/iterator_range.hpp>
 
 namespace anki {
 
@@ -22,16 +21,22 @@ public:
 	typedef std::vector<Renderable*> Renderables;
 	typedef std::vector<Light*> Lights;
 
-	boost::iterator_range<Renderables::iterator> getRenderables()
+	Renderables::iterator getRenderablesBegin()
 	{
-		return boost::iterator_range<Renderables::iterator>(
-			renderables.begin(), renderables.end());
+		return renderables.begin();
+	}
+	Renderables::iterator getRenderablesEnd()
+	{
+		return renderables.end();
 	}
 
-	boost::iterator_range<Lights::iterator> getLights()
+	Lights::iterator getLightsBegin()
+	{
+		return lights.begin();
+	}
+	Lights::iterator getLightsEnd()
 	{
-		return boost::iterator_range<Lights::iterator>(
-			lights.begin(), lights.end());
+		return lights.end();
 	}
 
 private:

+ 138 - 5
include/anki/util/Visitor.h

@@ -1,5 +1,9 @@
 /// @file
 /// The file contains visitor concepts
+///
+/// @par The main classes are:
+/// @li Visitable: For non related types
+/// @li VisitableCommonBase: For types with common base
 
 #ifndef ANKI_UTIL_VISITOR_H
 #define ANKI_UTIL_VISITOR_H
@@ -12,6 +16,7 @@ namespace anki {
 /// @addtogroup util
 /// @{
 
+/// Namespace for visitor internal classes
 namespace visitor_detail {
 
 /// A smart struct that given a type and a list of types finds a const integer
@@ -53,7 +58,11 @@ struct GetVariadicTypeId
 /// A struct that from a variadic arguments list it returnes the type using an
 /// ID.
 /// Example of usage:
-/// @code GetTypeUsingId<double, int, float>::DataType<0> @endcode
+/// @code
+/// GetTypeUsingId<std::string, int, float>::DataType<0> x = "a string";
+/// GetTypeUsingId<std::string, int, float>::DataType<1> y = 123;
+/// GetTypeUsingId<std::string, int, float>::DataType<2> y = 123.456f;
+/// @endcode
 template<typename... Types>
 struct GetTypeUsingId
 {
@@ -121,6 +130,49 @@ private:
 	}
 };
 
+/// Jump table for types with common base
+template<typename TVisitor, typename TBase, typename... Types>
+class JumpTableCommonBase
+{
+public:
+	using FuncPtr = void (*)(TVisitor&, TBase&);
+
+	JumpTableCommonBase()
+	{
+		init<Types...>();
+	}
+
+	/// Accessor
+	FuncPtr operator[](int i) const
+	{
+		return jumps[i];
+	}
+
+private:
+	/// Pointers to JumpPoint::visit static methods
+	std::array<FuncPtr, sizeof...(Types)> jumps;
+
+	template<typename T>
+	static void visit(TVisitor& v, TBase& base)
+	{
+		v.template visit(static_cast<T&>(base));
+	}
+
+	template<typename TFirst>
+	void init()
+	{
+		jumps[0] = &visit<TFirst>;
+	}
+
+	template<typename TFirst, typename TSecond, typename... Types_>
+	void init()
+	{
+		constexpr int i = sizeof...(Types) - sizeof...(Types_) - 1;
+		jumps[i] = &visit<TSecond>;
+		init<TFirst, Types_...>();
+	}
+};
+
 /// A simple struct that contains a static field with jump points
 template<typename TDerived, typename... Types>
 struct VisitorWrapper
@@ -128,15 +180,24 @@ struct VisitorWrapper
 	static const JumpTable<TDerived, Types...> jumpTable;
 };
 
+// A static
 template<typename TDerived, typename... Types>
 const JumpTable<TDerived, Types...>
 	VisitorWrapper<TDerived, Types...>::jumpTable;
 
-} // end namespace visitor_detail
+/// Jumps container for types with common base
+template<typename TDerived, typename TBase, typename... Types>
+struct VisitorWrapperCommonBase
+{
+	static const JumpTableCommonBase<TDerived, TBase, Types...> jumpTable;
+};
 
-//==============================================================================
-// Visitable                                                                   =
-//==============================================================================
+// A static
+template<typename TDerived, typename TBase, typename... Types>
+const JumpTableCommonBase<TDerived, TBase, Types...>
+	VisitorWrapperCommonBase<TDerived, TBase, Types...>::jumpTable;
+
+} // end namespace visitor_detail
 
 /// Visitable class
 template<typename... Types>
@@ -196,6 +257,78 @@ private:
 	int what = -1; ///< The type ID
 	void* address = nullptr; ///< The address to the data
 };
+
+/// Visitable for types with common base
+/// @tparam TBase The base class
+/// @tparam Types The types that compose the visitable. They are derived from
+///               TBase
+///
+/// @note In debug mode it uses dynamic cast as an extra protection reason
+template<typename TBase, typename... Types>
+class VisitableCommonBase
+{
+public:
+
+#if !defined(NDEBUG)
+	// Allow dynamic cast in acceptVisitor
+	virtual ~VisitableCommonBase()
+	{}
+#endif
+
+	int getVisitableTypeId() const
+	{
+		return what;
+	}
+
+	template<typename T>
+	static constexpr int getVariadicTypeId()
+	{
+		return visitor_detail::GetVariadicTypeId<Types...>::template get<T>();
+	}
+
+	/// Apply mutable visitor
+	template<typename TVisitor>
+	void acceptVisitor(TVisitor& v)
+	{
+		ANKI_ASSERT(what != -1);
+#if defined(NDEBUG)
+		TBase* base = static_cast<TBase*>(this);
+#else
+		TBase* base = dynamic_cast<TBase*>(this);
+		ANKI_ASSERT(base != nullptr);
+#endif
+		visitor_detail::VisitorWrapperCommonBase<TVisitor, TBase, Types...>::
+			jumpTable[what](v, *base);
+	}
+
+	/// Apply const visitor
+	template<typename TVisitor>
+	void acceptVisitor(TVisitor& v) const
+	{
+		typedef const TBase CTBase;
+		ANKI_ASSERT(what != -1);
+#if defined(NDEBUG)
+		CTBase* base = static_cast<CTBase*>(this);
+#else
+		CTBase* base = dynamic_cast<CTBase*>(this);
+		ANKI_ASSERT(base != nullptr);
+#endif
+		visitor_detail::VisitorWrapperCommonBase
+			<TVisitor,CTBase, const Types...>::
+			jumpTable[what](v, *base);
+	}
+
+	/// Setup the type ID
+	template<typename T>
+	void setupVisitable(const T*)
+	{
+		ANKI_ASSERT(what == -1); // Setting for second time not allowed
+		what = visitor_detail::GetVariadicTypeId<Types...>::template get<T>();
+	}
+
+private:
+	int what = -1; ///< The type ID
+};
 /// @}
 
 } // end namespace anki

+ 4 - 8
src/collision/Frustum.cpp

@@ -90,16 +90,14 @@ void PerspectiveFrustum::transformShape()
 void PerspectiveFrustum::transform(const Transform& trf_)
 {
 	trf.transform(trf_);
-	transformPlanes();
-	transformShape();
+	recalculate();
 }
 
 //==============================================================================
 void PerspectiveFrustum::setTransform(const Transform& trf_)
 {
 	trf = trf_;
-	transformPlanes();
-	transformShape();
+	recalculate();
 }
 
 //==============================================================================
@@ -203,16 +201,14 @@ OrthographicFrustum& OrthographicFrustum::operator=(
 void OrthographicFrustum::transform(const Transform& trf_)
 {
 	trf.transform(trf_);
-	transformPlanes();
-	transformShape();
+	recalculate();
 }
 
 //==============================================================================
 void OrthographicFrustum::setTransform(const Transform& trf_)
 {
 	trf = trf_;
-	transformPlanes();
-	transformShape();
+	recalculate();
 }
 
 //==============================================================================

+ 167 - 70
src/renderer/Drawer.cpp

@@ -271,7 +271,7 @@ void CollisionDebugDrawer::visit(const Plane& plane)
 	Quat q;
 	q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
 	Mat3 rot(q);
-	rot.rotateXAxis(Math::PI / 2);
+	rot.rotateXAxis(Math::PI / 2.0);
 	Mat4 trf(n * o, rot);
 
 	dbg->setModelMatrix(trf);
@@ -303,38 +303,38 @@ void CollisionDebugDrawer::visit(const Frustum& f)
 {
 	switch(f.getFrustumType())
 	{
-		case Frustum::FT_ORTHOGRAPHIC:
-			visit(static_cast<const OrthographicFrustum&>(f).getObb());
-			break;
-		case Frustum::FT_PERSPECTIVE:
+	case Frustum::FT_ORTHOGRAPHIC:
+		visit(static_cast<const OrthographicFrustum&>(f).getObb());
+		break;
+	case Frustum::FT_PERSPECTIVE:
+	{
+		dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
+		const PerspectiveFrustum& pf =
+			static_cast<const PerspectiveFrustum&>(f);
+
+		float camLen = pf.getFar();
+		float tmp0 = camLen / tan((Math::PI - pf.getFovX()) * 0.5) + 0.001;
+		float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
+
+		Vec3 points[] = {
+			Vec3(0.0, 0.0, 0.0), // 0: eye point
+			Vec3(-tmp0, tmp1, -camLen), // 1: top left
+			Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
+			Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
+			Vec3(tmp0, tmp1, -camLen) // 4: top right
+		};
+
+		const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
+			3, 3, 4, 4, 1};
+
+		dbg->begin();
+		for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
 		{
-			dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
-			const PerspectiveFrustum& pf =
-				static_cast<const PerspectiveFrustum&>(f);
-
-			float camLen = pf.getFar();
-			float tmp0 = camLen / tan((Math::PI - pf.getFovX()) * 0.5) + 0.001;
-			float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
-
-			Vec3 points[] = {
-				Vec3(0.0, 0.0, 0.0), // 0: eye point
-				Vec3(-tmp0, tmp1, -camLen), // 1: top left
-				Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
-				Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
-				Vec3(tmp0, tmp1, -camLen) // 4: top right
-			};
-
-			const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
-				3, 3, 4, 4, 1};
-
-			dbg->begin();
-			for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
-			{
-				dbg->pushBackVertex(points[indeces[i]]);
-			}
-			dbg->end();
-			break;
+			dbg->pushBackVertex(points[indeces[i]]);
 		}
+		dbg->end();
+		break;
+	}
 	}
 }
 
@@ -420,14 +420,32 @@ void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
 //==============================================================================
 void SceneDebugDrawer::draw(SceneNode& node)
 {
-	if(isFlagEnabled(DF_FRUSTUMABLE) && node.getFrustumable())
+	// Nothing to render?
+	if(getFlagsBitmask() == 0)
 	{
-		draw(*node.getFrustumable());
+		return;
 	}
 
-	if(isFlagEnabled(DF_SPATIAL) && node.getSpatial())
+	Movable* mv = node.getMovable();
+	if(mv)
+	{
+		dbg->setModelMatrix(Mat4(mv->getWorldTransform()));
+	}
+	else
 	{
-		draw(*node.getSpatial());
+		dbg->setModelMatrix(Mat4::getIdentity());
+	}
+
+	Frustumable* fr;
+	if(isFlagEnabled(DF_FRUSTUMABLE) && (fr = node.getFrustumable()))
+	{
+		draw(*fr);
+	}
+
+	Spatial* sp;
+	if(isFlagEnabled(DF_SPATIAL) && (sp = node.getSpatial()))
+	{
+		draw(*sp);
 	}
 }
 
@@ -480,26 +498,120 @@ void SceneDebugDrawer::draw(OctreeNode& octnode, uint depth,
 // RenderableDrawer                                                            =
 //==============================================================================
 
-/// Set the uniform using this visitor
-struct SetUniformVisitor
+//==============================================================================
+
+enum BuildinId
 {
-	const ShaderProgramUniformVariable* uni;
+	BI_UNITIALIZED = 0,
+	BT_NO_BUILDIN = 1,
+	BI_MODEL_VIEW_PROJECTION_MATRIX,
+	BI_NORMAL_MATRIX
+};
 
-	template<typename T>
-	void visit(const T& x)
-	{
-		uni->set(x);
+static std::array<const char*, 2> buildinNames = {{
+	"modelViewProjectionMat",
+	"normalMat"
+}};
+
+template<typename T>
+static void uniSet(const ShaderProgramUniformVariable& uni, const T& x)
+{
+	ANKI_ASSERT(0);
+}
+
+#define TEMPLATE_SPECIALIZATION(type) \
+	template<> \
+	void uniSet<type>(const ShaderProgramUniformVariable& uni, const type& x) \
+	{ \
+		uni.set(x); \
 	}
-};
 
+TEMPLATE_SPECIALIZATION(float)
+TEMPLATE_SPECIALIZATION(Vec2)
+TEMPLATE_SPECIALIZATION(Vec3)
+TEMPLATE_SPECIALIZATION(Vec4)
+TEMPLATE_SPECIALIZATION(Mat3)
+TEMPLATE_SPECIALIZATION(Mat4)
+
+// Texture specialization
 template<>
-void SetUniformVisitor::visit<TextureResourcePointer>(
+void uniSet<TextureResourcePointer>(
+	const ShaderProgramUniformVariable& uni,
 	const TextureResourcePointer& x)
 {
 	const Texture* tex = x.get();
-	uni->set(*tex);
+	uni.set(*tex);
 }
 
+/// XXX
+struct SetupMaterialVariableVisitor
+{
+	PassLevelKey key;
+	const Camera* cam = nullptr;
+	Renderer* r = nullptr;
+	Renderable* renderable = nullptr;
+
+	template<typename TProp>
+	void visit(TProp& x)
+	{
+		MaterialVariableProperty<typename TProp::Value>& mprop =
+			static_cast<MaterialVariableProperty<typename TProp::Value>&>(x);
+
+		const MaterialVariable& mv = mprop.getMaterialVariable();
+
+		const ShaderProgramUniformVariable* uni =
+			mv.findShaderProgramUniformVariable(key);
+
+		if(!uni)
+		{
+			return;
+		}
+
+		// Set buildin id
+		//
+		if(mprop.getBuildinId() == BI_UNITIALIZED)
+		{
+			const std::string name = mv.getName();
+
+			for(uint32_t i = 0; i < buildinNames.size(); i++)
+			{
+				if(name == buildinNames[i])
+				{
+					mprop.setBuildinId(i + 2);
+					break;
+				}
+			}
+
+			if(mprop.getBuildinId() == BI_UNITIALIZED)
+			{
+				mprop.setBuildinId(BT_NO_BUILDIN);
+			}
+		}
+
+		// Set uniform
+		//
+		const Transform* rwtrf = renderable->getRenderableWorldTransform();
+
+		Mat4 mMat = (rwtrf) ? Mat4(*rwtrf) : Mat4::getIdentity();
+		Mat4 vpMat = cam->getProjectionMatrix() * cam->getViewMatrix();
+		Mat4 mvpMat = vpMat * mMat;
+		Mat4 mvMat = cam->getViewMatrix() * mMat;
+
+		switch(mprop.getBuildinId())
+		{
+		case BT_NO_BUILDIN:
+			uniSet(*uni, mprop.getValue());
+			break;
+		case BI_MODEL_VIEW_PROJECTION_MATRIX:
+			uni->set(mvpMat);
+			break;
+		case BI_NORMAL_MATRIX:
+			uni->set(mvMat.getRotationPart());
+			break;
+		}
+	}
+};
+
 //==============================================================================
 void RenderableDrawer::setupShaderProg(
 	const PassLevelKey& key,
@@ -520,33 +632,18 @@ void RenderableDrawer::setupShaderProg(
 
 	sprog.bind();
 	
-	SetUniformVisitor vis;
+	SetupMaterialVariableVisitor vis;
 
-	for(const MaterialVariable& mv : mtl.getVariables())
-	{
-		const ShaderProgramUniformVariable* uni = 
-			mv.findShaderProgramUniformVariable(key);
+	vis.cam = &cam;
+	vis.key = key;
+	vis.renderable = &renderable;
+	vis.r = r;
 
-		if(!uni)
-		{
-			continue;
-		}
-
-		const std::string& name = uni->getName();
-
-		if(name == "modelViewProjectionMat")
-		{
-			Mat4 mvp = 
-				cam.getProjectionMatrix() * cam.getViewMatrix()
-				* Mat4(*renderable.getRenderableWorldTransform());
-
-			uni->set(mvp);
-		}
-		else
-		{
-			vis.uni = uni;
-			mv.acceptVisitor(vis);
-		}
+	for(auto it = renderable.getPropertiesBegin();
+		it != renderable.getPropertiesEnd(); ++it)
+	{
+		PropertyBase* pbase = *it;
+		pbase->acceptVisitor(vis);
 	}
 }
 

+ 1 - 1
src/renderer/MainRenderer.cpp

@@ -112,7 +112,7 @@ void MainRenderer::render(Scene& scene)
 	GlStateSingleton::get().disable(GL_DEPTH_TEST);
 	GlStateSingleton::get().disable(GL_BLEND);
 	sProg->bind();
-	const Texture& finalFai = ms.getDiffuseFai();
+	const Texture& finalFai = ms.getNormalFai();
 	sProg->findUniformVariableByName("rasterImage")->set(finalFai);
 	drawQuad();
 }

+ 4 - 4
src/renderer/Ms.cpp

@@ -72,11 +72,11 @@ void Ms::run()
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 	// render all
-	for(Renderable* node :
-		r->getScene().getVisibilityInfo().getRenderables())
+	VisibilityInfo& vi = r->getScene().getVisibilityInfo();
+	for(auto it = vi.getRenderablesBegin();
+		it != vi.getRenderablesEnd(); ++it)
 	{
-		r->getSceneDrawer().render(r->getScene().getActiveCamera(),
-			0, *node);
+		r->getSceneDrawer().render(r->getScene().getActiveCamera(), 0, *(*it));
 	}
 
 	// restore depth

+ 2 - 2
src/renderer/Sm.cpp

@@ -124,9 +124,9 @@ void Sm::run(Light& light, float distance)
 	vt.test(slight, r->getScene(), vi);
 
 	// render all
-	for(Renderable* node : vi.getRenderables())
+	for(auto it = vi.getRenderablesBegin(); it != vi.getRenderablesEnd(); ++it)
 	{
-		r->getSceneDrawer().render(r->getScene().getActiveCamera(), 1, *node);
+		r->getSceneDrawer().render(r->getScene().getActiveCamera(), 1, *(*it));
 	}
 
 	// restore GL

+ 6 - 2
src/scene/Renderable.cpp

@@ -13,7 +13,7 @@ struct CreateNewPropertyVisitor
 {
 	const MaterialVariable* mvar;
 	PropertyMap* pmap;
-	Renderable::Properties* rprops;
+	Renderable::MaterialVariableProperties* rprops;
 
 	template<typename T>
 	void visit(const T&) const
@@ -21,7 +21,7 @@ struct CreateNewPropertyVisitor
 		MaterialVariableProperty<T>* prop = new MaterialVariableProperty<T>(
 			mvar->getName().c_str(),
 			&(mvar->getValue<T>()),
-			!mvar->getInitialized());
+			mvar);
 
 		pmap->addNewProperty(prop);
 		rprops->push_back(prop);
@@ -32,6 +32,10 @@ struct CreateNewPropertyVisitor
 // Renderable                                                                  =
 //==============================================================================
 
+//==============================================================================
+Renderable::~Renderable()
+{}
+
 //==============================================================================
 void Renderable::init(PropertyMap& pmap)
 {

+ 9 - 2
src/scene/VisibilityTester.cpp

@@ -20,8 +20,15 @@ void VisibilityTester::test(Frustumable& cam, Scene& scene,
 	for(auto it = scene.getAllNodesBegin(); it != scene.getAllNodesEnd(); it++)
 	{
 		SceneNode* node = *it;
-		Spatial* sp = node->getSpatial();
 
+		Frustumable* fr = node->getFrustumable();
+		// Wont check the same
+		if(&cam == fr)
+		{
+			continue;
+		}
+
+		Spatial* sp = node->getSpatial();
 		if(!sp)
 		{
 			continue;
@@ -49,4 +56,4 @@ void VisibilityTester::test(Frustumable& cam, Scene& scene,
 	}
 }
 
-} // end namespace
+} // end namespace anki

+ 14 - 6
testapp/Main.cpp

@@ -63,12 +63,17 @@ void init()
 	cam->setAll(
 		MainRendererSingleton::get().getAspectRatio() * Math::toRad(ang),
 		Math::toRad(ang), 0.5, 200.0);
-	/*cam->moveLocalY(3.0);
-	cam->moveLocalZ(5.7);
-	cam->moveLocalX(-0.3);
-	cam->lookAtPoint(Vec3(0.0));*/
+	cam->setLocalTransform(Transform(Vec3(0.0, 3.0, 8.0), Mat3::getIdentity(),
+		1.0));
 	scene.setActiveCamera(cam);
 
+	// XXX
+	PerspectiveCamera* ccam = new PerspectiveCamera("ccam",
+		&scene, Movable::MF_NONE, nullptr);
+	ccam->setAll(
+		MainRendererSingleton::get().getAspectRatio() * Math::toRad(ang),
+		Math::toRad(ang), 0.5, 20.0);
+
 	// lights
 
 	SpotLight* spot = new SpotLight("spot0", &scene, Movable::MF_NONE, nullptr);
@@ -106,6 +111,10 @@ void mainLoopExtra()
 	{
 		mover = &SceneSingleton::get().getActiveCamera();
 	}
+	if(in.getKey(SDL_SCANCODE_2))
+	{
+		mover = SceneSingleton::get().findSceneNode("ccam")->getMovable();
+	}
 
 	if(in.getKey(SDL_SCANCODE_UP)) mover->rotateLocalX(ang);
 	if(in.getKey(SDL_SCANCODE_DOWN)) mover->rotateLocalX(-ang);
@@ -294,9 +303,8 @@ int main(int argc, char* argv[])
 	catch(std::exception& e)
 	{
 		std::cerr << "Aborting: " << e.what() << std::endl;
-		//abort();
 		exitCode = 1;
 	}
-
+	ANKI_LOGI("Bye!!");
 	return exitCode;
 }