Browse Source

Scene rework. WONT COMPILE

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
724858f09f

+ 29 - 8
include/anki/gl/Drawcall.h

@@ -3,6 +3,7 @@
 
 #include "anki/gl/Ogl.h"
 #include "anki/util/StdTypes.h"
+#include "anki/util/Array.h"
 
 namespace anki {
 
@@ -12,18 +13,38 @@ namespace anki {
 /// A GL drawcall
 struct Drawcall
 {
-	GLenum primitiveType = 0;
-	GLenum indicesType = 0;
-	U32 instancesCount = 1;
-	U32 drawcallCount = 1;
-	Array<U32, ANKI_MAX_MULTIDRAW_PRIMITIVES> indicesCountArray;
-	Array<PtrSize, ANKI_MAX_MULTIDRAW_PRIMITIVES> offsetsArray;
-
-	/// Execute the dracall
+	GLenum primitiveType;
+	
+	/// Type of the indices. If zero then draw with glDrawArraysXXX
+	GLenum indicesType; 
+
+	U32 instancesCount;
+
+	/// Used in glMultiDrawXXX
+	U32 drawCount;
+
+	/// The indices or elements
+	union
+	{
+		U32 count;
+		Array<U32, ANKI_MAX_MULTIDRAW_PRIMITIVES> countArray;
+	};
+
+	union
+	{
+		PtrSize offset;
+		Array<PtrSize, ANKI_MAX_MULTIDRAW_PRIMITIVES> offsetArray;
+	};
+
+	Drawcall();
+
+	/// Execute the drawcall
 	void enque();
 };
 /// @}
 
+static_assert(sizeof(GLsizei) == sizeof(U32), "Wrong assumption");
+
 } // end namespace anki
 
 #endif

+ 51 - 3
include/anki/scene/Camera.h

@@ -12,7 +12,8 @@ namespace anki {
 /// @{
 
 /// Camera SceneNode interface class
-class Camera: public SceneNode
+class Camera: public SceneNode, public MoveComponent, public FrustumComponent,
+	public SpatialComponent
 {
 public:
 	/// @note Don't EVER change the order
@@ -27,7 +28,6 @@ public:
 	/// @{
 	Camera(
 		const char* name, SceneGraph* scene, // SceneNode
-		Frustum* frustum, // Spatial & Frustumable
 		CameraType type); // Self
 
 	virtual ~Camera();
@@ -51,13 +51,29 @@ public:
 	void componentUpdated(SceneComponent& comp, 
 		SceneComponent::UpdateType) override
 	{
-		if(comp.getId() == SceneComponent::getVariadicTypeId<MoveComponent>())
+		if(comp.getTypeId() == SceneComponent::getTypeIdOf<MoveComponent>())
 		{
 			moveUpdate(static_cast<MoveComponent&>(comp));
 		}
 	}
 	/// @}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	Vec3 getSpatialOrigin()
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
+	/// @name FrustumComponent virtuals
+	/// @{
+	Vec3 getFrustumOrigin()
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 	void lookAtPoint(const Vec3& point);
 
 protected:
@@ -119,6 +135,22 @@ public:
 	}
 	/// @}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	CollisionShape& getSpatialCollisionShape()
+	{
+		return frustum;
+	}
+	/// @}
+
+	/// @name FrustumComponent virtuals
+	/// @{
+	Frustum& getFrustum()
+	{
+		return frustum;
+	}
+	/// @}
+
 private:
 	PerspectiveFrustum frustum;
 };
@@ -171,6 +203,22 @@ public:
 	}
 	/// @}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	CollisionShape& getSpatialCollisionShape()
+	{
+		return frustum;
+	}
+	/// @}
+
+	/// @name FrustumComponent virtuals
+	/// @{
+	Frustum& getFrustum()
+	{
+		return frustum;
+	}
+	/// @}
+
 private:
 	OrthographicFrustum frustum;
 };

+ 12 - 32
include/anki/scene/FrustumComponent.h

@@ -23,24 +23,16 @@ public:
 	/// @{
 
 	/// Pass the frustum here so we can avoid the virtuals
-	FrustumComponent(SceneNode* node, Frustum* fr)
-		: SceneComponent(this, node), frustum(fr), origin(0.0)
+	FrustumComponent(SceneNode* node)
+		: SceneComponent(this, node)
 	{
-		ANKI_ASSERT(frustum);
 		markForUpdate();
 	}
 	/// @}
 
 	/// @name Accessors
 	/// @{
-	const Frustum& getFrustum() const
-	{
-		return *frustum;
-	}
-	Frustum& getFrustum()
-	{
-		return *frustum;
-	}
+	virtual Frustum& getFrustum() = 0;
 
 	const Mat4& getProjectionMatrix() const
 	{
@@ -70,15 +62,7 @@ public:
 	}
 
 	/// Get the origin for sorting and visibility tests
-	const Vec3& getOrigin() const
-	{
-		return origin;
-	}
-	/// You need to mark it for update after calling this
-	void setOrigin(const Vec3& ori)
-	{
-		origin = ori;
-	}
+	virtual Vec3 getFrustumOrigin() = 0;
 
 	void setVisibilityTestResults(VisibilityTestResults* visible_)
 	{
@@ -99,19 +83,18 @@ public:
 	}
 
 	/// Is a spatial inside the frustum?
-	Bool insideFrustum(const SpatialComponent& sp) const
+	Bool insideFrustum(SpatialComponent& sp)
 	{
-		return frustum->insideFrustum(sp.getSpatialCollisionShape());
+		return getFrustum().insideFrustum(sp.getSpatialCollisionShape());
 	}
 
 	/// Is a collision shape inside the frustum?
-	Bool insideFrustum(const CollisionShape& cs) const
+	Bool insideFrustum(const CollisionShape& cs)
 	{
-		return frustum->insideFrustum(cs);
+		return getFrustum().insideFrustum(cs);
 	}
 
-	/// @name SceneComponent overrides
-	/// @{
+	/// Override SceneComponent::update
 	Bool update(SceneNode&, F32, F32, UpdateType updateType) override
 	{
 		if(updateType == ASYNC_UPDATE)
@@ -126,20 +109,17 @@ public:
 		}
 	}
 
-	void reset()
+	/// Override SceneComponent::reset
+	void reset() override
 	{
 		visible = nullptr;
 	}
-	/// @}
+
 private:
-	Frustum* frustum = nullptr;
 	Mat4 projectionMat = Mat4::getIdentity();
 	Mat4 viewMat = Mat4::getIdentity();
 	Mat4 viewProjectionMat = Mat4::getIdentity();
 
-	/// A cached value
-	Vec3 origin;
-
 	/// Visibility stuff. It's per frame so the pointer is invalid on the next 
 	/// frame and before any visibility tests are run
 	VisibilityTestResults* visible = nullptr;

+ 40 - 3
include/anki/scene/Light.h

@@ -59,7 +59,8 @@ private:
 /// Specular intensity of light:    Sl
 /// Specular intensity of material: Sm
 /// @endcode
-class Light: public SceneNode
+class Light: public SceneNode, public LightComponent, public MoveComponent, 
+	public SpatialComponent
 {
 public:
 	enum LightType
@@ -73,7 +74,6 @@ public:
 	/// @{
 	Light(
 		const char* name, SceneGraph* scene, // SceneNode
-		CollisionShape* cs, // SpatialComponent
 		LightType t); // Self
 	/// @}
 
@@ -173,6 +173,14 @@ public:
 		flaresTex.load(filename);
 	}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	Vec3 getSpatialOrigin()
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 protected:
 	/// One of the frustums got updated
 	void frustumUpdate();
@@ -230,12 +238,20 @@ public:
 		SceneComponent::UpdateType uptype) override;
 	/// @}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	CollisionShape& getSpatialCollisionShape()
+	{
+		return sphereW;
+	}
+	/// @}
+
 public:
 	Sphere sphereW = Sphere(Vec3(0.0), 1.0);
 };
 
 /// Spot light
-class SpotLight: public Light
+class SpotLight: public Light, public FrustumComponent
 {
 public:
 	/// @name Constructors/Destructor
@@ -302,6 +318,27 @@ public:
 		SceneComponent::UpdateType uptype) override;
 	/// @}
 
+	/// @name SpatialComponent virtuals
+	/// @{
+	CollisionShape& getSpatialCollisionShape()
+	{
+		return frustum;
+	}
+	/// @}
+
+	/// @name FrustumVirtuals
+	/// @{
+	Vec3 getFrustumOrigin()
+	{
+		return getWorldTransform().getOrigin();
+	}
+
+	Frustum& getFrustum()
+	{
+		return frustum;
+	}
+	/// @}
+
 	void loadTexture(const char* filename)
 	{
 		tex.load(filename);

+ 4 - 45
include/anki/scene/ModelNode.h

@@ -18,36 +18,17 @@ class ModelPatchNode;
 /// @{
 
 /// A model instance
-class ModelPatchNodeInstance: public SceneNode, public MoveComponent, 
-	public SpatialComponent
+class Instance: public SceneNode, public MoveComponent
 {
-	friend class ModelPatchNode;
-	friend class ModelNode;
-
 public:
 	ModelPatchNodeInstance(
-		const char* name, SceneGraph* scene, // SceneNode
-		ModelPatchNode* modelPatchNode); // Self
-
-	/// @name MoveComponent virtuals
-	/// @{
-
-	/// Overrides MoveComponent::moveUpdate(). This does:
-	/// - Update the collision shape
-	/// - If it's the last instance update the parent's CS.
-	void moveUpdate();
-	/// @}
-
-private:
-	Obb obb; ///< In world space
-	ModelPatchNode* modelPatchNode; ///< Keep the father here
+		const char* name, SceneGraph* scene);
 };
 
 /// A fragment of the ModelNode
-class ModelPatchNode: public SceneNode, public MoveComponent, 
+class ModelPatchNode: public SceneNode, 
 	public RenderComponent, public SpatialComponent
 {
-	friend class ModelPatchNodeInstance;
 	friend class ModelNode;
 
 public:
@@ -60,14 +41,6 @@ public:
 	~ModelPatchNode();
 	/// @}
 
-	/// @name MoveComponent virtuals
-	/// @{
-
-	/// Overrides MoveComponent::moveUpdate(). This does:
-	/// - Update the collision shape
-	void moveUpdate();
-	/// @}
-
 	/// @name RenderComponent virtuals
 	/// @{
 
@@ -76,14 +49,7 @@ public:
 		const PassLodKey& key, 
 		const Vao*& vao, const ShaderProgram*& prog,
 		const U32* subMeshIndicesArray, U subMeshIndicesCount,
-		Array<U32, ANKI_MAX_MULTIDRAW_PRIMITIVES>& indicesCountArray,
-		Array<const void*, ANKI_MAX_MULTIDRAW_PRIMITIVES>& indicesOffsetArray, 
-		U32& drawcallCount) const
-	{
-		modelPatch->getRenderingDataSub(key, vao, prog, 
-			subMeshIndicesArray, subMeshIndicesCount, 
-			indicesCountArray, indicesOffsetArray, drawcallCount);
-	}
+		Drawcall& dracall);
 
 	/// Implements  RenderComponent::getMaterial
 	const Material& getMaterial()
@@ -93,13 +59,6 @@ public:
 
 	/// Overrides RenderComponent::getRenderComponentWorldTransforms
 	const Transform* getRenderWorldTransforms();
-
-	/// Overrides RenderComponent::getRenderComponentInstancesCount
-	U32 getRenderInstancesCount()
-	{
-		// return this and the instances 
-		return (transforms.size() > 0) ? transforms.size() : 1;
-	}
 	/// @}
 
 private:

+ 5 - 4
include/anki/scene/RenderComponent.h

@@ -169,7 +169,7 @@ public:
 	/// @param node Pass node to steal it's allocator
 	RenderComponent(SceneNode* node);
 
-	virtual ~RenderComponent();
+	~RenderComponent();
 
 	/// Get information for rendering.
 	/// Given an array of submeshes that are visible return the correct indices
@@ -178,7 +178,7 @@ public:
 		const PassLodKey& key, 
 		const U32* subMeshIndicesArray, U subMeshIndicesCount,
 		const Vao*& vao, const ShaderProgram*& prog,
-		Drawcall& drawcall) const = 0;
+		Drawcall& drawcall) = 0;
 
 	/// Access the material
 	virtual const Material& getMaterial() = 0;
@@ -211,10 +211,11 @@ public:
 		}
 	}
 
+protected:
+	void init();
+
 private:
 	Variables vars;
-
-	void init(SceneNode& node);
 };
 /// @}
 

+ 1 - 1
include/anki/scene/SceneComponent.h

@@ -82,7 +82,7 @@ public:
 	}
 
 protected:
-	Timestamp timestamp;
+	Timestamp timestamp; ///< Indicates when an update happened
 };
 
 } // end namespace anki

+ 2 - 13
include/anki/scene/SceneNode.h

@@ -176,19 +176,8 @@ public:
 	}
 
 protected:
-	/// Create a new component and append it to the components container
-	template<typename T, typename... Args>
-	T* newComponent(Args&&... args)
-	{
-		T* comp = nullptr;
-		SceneAllocator<T> al = getSceneAllocator();
-
-		comp = al.allocate(1);
-		al.construct(comp, std::forward<Args>(args)...);
-
-		components.push_back(comp);
-		return comp;
-	}
+	/// Append a component to the components container
+	void addComponent(SceneComponent* comp);
 
 private:
 	SceneGraph* scene = nullptr;

+ 7 - 20
include/anki/scene/SpatialComponent.h

@@ -37,20 +37,15 @@ public:
 
 	/// Pass the collision shape here so we can avoid the virtuals
 	/// @param node The scene node. Used only to steal it's allocators
-	/// @param cs The collision shape
 	/// @param flags A mask of SpatialFlag
-	SpatialComponent(SceneNode* node, const CollisionShape* cs,
-		U32 flags = SF_NONE);
+	SpatialComponent(SceneNode* node, U32 flags = SF_NONE);
 
 	// Remove from current OctreeNode
 	~SpatialComponent();
 
 	/// @name Accessors
 	/// @{
-	const CollisionShape& getSpatialCollisionShape() const
-	{
-		return *spatialCs;
-	}
+	virtual CollisionShape& getSpatialCollisionShape() = 0;
 
 	const Aabb& getAabb() const
 	{
@@ -58,11 +53,12 @@ public:
 	}
 
 	/// Get optimal collision shape for visibility tests
-	const CollisionShape& getVisibilityCollisionShape() const
+	CollisionShape& getVisibilityCollisionShape()
 	{
-		if(spatialCs->getCollisionShapeType() == CollisionShape::CST_SPHERE)
+		CollisionShape& cs = getSpatialCollisionShape();
+		if(cs.getCollisionShapeType() == CollisionShape::CST_SPHERE)
 		{
-			return *spatialCs;
+			return cs;
 		}
 		else
 		{
@@ -72,14 +68,7 @@ public:
 
 	/// Used for sorting spatials. In most object the origin is the center of
 	/// mess but for cameras the origin is the eye point
-	const Vec3& getOrigin() const
-	{
-		return origin;
-	}
-	void setOrigin(const Vec3& o)
-	{
-		origin = o;
-	}
+	virtual Vec3 getSpatialOrigin() = 0;
 	/// @}
 
 	/// The derived class has to manually call this method when the collision 
@@ -98,9 +87,7 @@ public:
 	/// @}
 
 private:
-	const CollisionShape* spatialCs = nullptr;
 	Aabb aabb; ///< A faster shape
-	Vec3 origin; ///< Cached value
 };
 /// @}
 

+ 47 - 18
src/gl/Drawcall.cpp

@@ -1,33 +1,40 @@
 #include "anki/gl/Drawcall.h"
 #include "anki/util/Assert.h"
+#include <cstring>
 
 namespace anki {
 
+//==============================================================================
+Drawcall::Drawcall()
+{
+	memset(this, 0, sizeof(Drawcall));
+	instancesCount = 1;
+	drawCount = 1;
+}
+
 //==============================================================================
 void Drawcall::enque()
 {
-	ANKI_ASSERT(primitiveType && instancesCount > 0 && drawcallCount > 0
-		&& offsetsArray);
+	ANKI_ASSERT(primitiveType && instancesCount > 0);
+	ANKI_ASSERT(drawCount > 0 && drawCount <= ANKI_MAX_MULTIDRAW_PRIMITIVES);
 
-	if(indicesCountArray != nullptr)
+	if(indicesType != 0)
 	{
 		// DrawElements
 
-		ANKI_ASSERT(indicesCountArray && indicesType);
-
 		if(instancesCount == 1)
 		{
 			// No  instancing
 
-			if(drawcallCount == 1)
+			if(drawCount == 1)
 			{
 				// No multidraw
 
 				glDrawElements(
 					primitiveType, 
-					indicesCountArray[0], 
+					countArray[0], 
 					indicesType, 
-					offsetsArray[0]);
+					(const void*)offsetArray[0]);
 			}
 			else
 			{
@@ -36,18 +43,18 @@ void Drawcall::enque()
 #if ANKI_GL == ANKI_GL_DESKTOP
 				glMultiDrawElements(
 					primitiveType, 
-					indicesCountArray, 
+					(int*)&countArray[0],
 					indicesType, 
-					offsetsArray, 
-					drawcallCount);
+					(const void**)&offsetArray[0], 
+					drawCount);
 #else
-				for(U i = 0; i < drawcallCount; i++)
+				for(U i = 0; i < drawCount; i++)
 				{
 					glDrawElements(
 						primitiveType, 
-						indicesCountArray[i],
+						countArray[i],
 						indicesType,
-						offsetsArray[i]);
+						offsetArray[i]);
 				}
 #endif
 			}
@@ -57,16 +64,38 @@ void Drawcall::enque()
 			// Instancing
 			glDrawElementsInstanced(
 				primitiveType, 
-				indicesCountArray[0], 
+				countArray[0], 
 				indicesType, 
-				offsetsArray[0], 
+				(const void*)offsetArray[0], 
 				instancesCount);
 		}
 	}
 	else
 	{
-		// Draw arrays
-		ANKI_ASSERT(0 && "ToDo");
+		// DrawArrays
+
+		if(instancesCount == 1)
+		{
+			// No instancing
+
+			if(drawCount == 1)
+			{
+				// No multidraw
+
+				glDrawArrays(primitiveType, 0, countArray[0]);
+			}
+			else
+			{
+				// Multidraw
+
+				ANKI_ASSERT(0 && "TODO");
+			}
+		}
+		else
+		{
+			// Instancing
+			ANKI_ASSERT(0 && "TODO");
+		}
 	}
 }
 

+ 15 - 14
src/scene/Camera.cpp

@@ -9,14 +9,17 @@ namespace anki {
 //==============================================================================
 Camera::Camera(
 	const char* name, SceneGraph* scene, // SceneNode
-	Frustum* frustum, // SpatialComponent & FrustumComponent
 	CameraType type_) 
-	: SceneNode(name, scene), type(type_)
+	:	SceneNode(name, scene), 
+		MoveComponent(this),
+		FrustumComponent(this),
+		SpatialComponent(this),
+		type(type_)
 {
 	// Init components
-	newComponent<MoveComponent>(this);
-	newComponent<SpatialComponent>(this, frustum);
-	newComponent<FrustumComponent>(this, frustum);
+	addComponent(static_cast<MoveComponent*>(this));
+	addComponent(static_cast<SpatialComponent*>(this));
+	addComponent(static_cast<FrustumComponent*>(this));
 }
 
 //==============================================================================
@@ -26,7 +29,7 @@ Camera::~Camera()
 //==============================================================================
 void Camera::lookAtPoint(const Vec3& point)
 {
-	MoveComponent& move = getComponent<MoveComponent>();
+	MoveComponent& move = *this;
 
 	const Vec3& j = Vec3(0.0, 1.0, 0.0);
 	Vec3 vdir = (point - move.getLocalTransform().getOrigin()).getNormalized();
@@ -42,13 +45,13 @@ void Camera::lookAtPoint(const Vec3& point)
 void Camera::frustumUpdate()
 {
 	// Frustum
-	FrustumComponent& fr = getComponent<FrustumComponent>();
+	FrustumComponent& fr = *this;
 	fr.setProjectionMatrix(fr.getFrustum().calculateProjectionMatrix());
 	fr.setViewProjectionMatrix(fr.getProjectionMatrix() * fr.getViewMatrix());
 	fr.markForUpdate();
 
 	// Spatial
-	SpatialComponent& sp = getComponent<SpatialComponent>();
+	SpatialComponent& sp = *this;
 	sp.markForUpdate();
 }
 
@@ -56,16 +59,14 @@ void Camera::frustumUpdate()
 void Camera::moveUpdate(MoveComponent& move)
 {
 	// Frustum
-	FrustumComponent& fr = getComponent<FrustumComponent>();
+	FrustumComponent& fr = *this;
 	fr.setViewMatrix(Mat4(move.getWorldTransform().getInverse()));
 	fr.setViewProjectionMatrix(fr.getProjectionMatrix() * fr.getViewMatrix());
-	fr.setOrigin(move.getWorldTransform().getOrigin());
 	fr.markForUpdate();
 	fr.getFrustum().setTransform(move.getWorldTransform());
 
 	// Spatial
-	SpatialComponent& sp = getComponent<SpatialComponent>();
-	sp.setOrigin(move.getWorldTransform().getOrigin());
+	SpatialComponent& sp = *this;
 	sp.markForUpdate();
 }
 
@@ -75,7 +76,7 @@ void Camera::moveUpdate(MoveComponent& move)
 
 //==============================================================================
 PerspectiveCamera::PerspectiveCamera(const char* name, SceneGraph* scene)
-	: Camera(name, scene, &frustum, CT_PERSPECTIVE)
+	: Camera(name, scene, CT_PERSPECTIVE)
 {}
 
 //==============================================================================
@@ -84,7 +85,7 @@ PerspectiveCamera::PerspectiveCamera(const char* name, SceneGraph* scene)
 
 //==============================================================================
 OrthographicCamera::OrthographicCamera(const char* name, SceneGraph* scene)
-	: Camera(name, scene, &frustum, CT_ORTHOGRAPHIC)
+	: Camera(name, scene, CT_ORTHOGRAPHIC)
 {}
 
 } // end namespace anki

+ 14 - 10
src/scene/Light.cpp

@@ -9,13 +9,17 @@ namespace anki {
 //==============================================================================
 Light::Light(
 	const char* name, SceneGraph* scene, // SceneNode
-	CollisionShape* cs, // Spatial
 	LightType t) // Self
-	: SceneNode(name, scene), type(t)
+	:	SceneNode(name, scene),
+		LightComponent(this),
+		MoveComponent(this),
+		SpatialComponent(this),
+		type(t)
 {
-	newComponent<MoveComponent>(this);
-	newComponent<SpatialComponent>(this, cs);
-	newComponent<LightComponent>(this);
+	// Init components
+	addComponent(static_cast<LightComponent*>(this));
+	addComponent(static_cast<MoveComponent*>(this));
+	addComponent(static_cast<SpatialComponent*>(this));
 }
 
 //==============================================================================
@@ -48,7 +52,6 @@ void Light::moveUpdate(MoveComponent& move)
 		fr.setProjectionMatrix(fr.getFrustum().calculateProjectionMatrix());
 		fr.setViewProjectionMatrix(
 			fr.getProjectionMatrix() * fr.getViewMatrix());
-		fr.setOrigin(move.getWorldTransform().getOrigin());
 		fr.getFrustum().setTransform(move.getWorldTransform());
 
 		fr.markForUpdate();
@@ -56,7 +59,6 @@ void Light::moveUpdate(MoveComponent& move)
 
 	// Update the spatial
 	SpatialComponent& sp = getComponent<SpatialComponent>();
-	sp.setOrigin(move.getWorldTransform().getOrigin());
 	sp.markForUpdate();
 }
 
@@ -66,7 +68,7 @@ void Light::moveUpdate(MoveComponent& move)
 
 //==============================================================================
 PointLight::PointLight(const char* name, SceneGraph* scene)
-	:	Light(name, scene, &sphereW, LT_POINT)
+	:	Light(name, scene, LT_POINT)
 {}
 
 //==============================================================================
@@ -87,9 +89,11 @@ void PointLight::componentUpdated(SceneComponent& comp,
 
 //==============================================================================
 SpotLight::SpotLight(const char* name, SceneGraph* scene)
-	: Light(name, scene, &frustum, LT_SPOT)
+	:	Light(name, scene, LT_SPOT),
+		FrustumComponent(this)
 {
-	newComponent<FrustumComponent>(this, &frustum);
+	// Init components
+	addComponent(static_cast<FrustumComponent*>(this));
 
 	const F32 ang = toRad(45.0);
 	setOuterAngle(ang / 2.0);

+ 19 - 32
src/scene/ModelNode.cpp

@@ -8,43 +8,16 @@
 namespace anki {
 
 //==============================================================================
-// ModelPatchNodeInstance                                                      =
+// Instance                                                                    =
 //==============================================================================
 
 //==============================================================================
-ModelPatchNodeInstance::ModelPatchNodeInstance(
-	const char* name, SceneGraph* scene, // Scene
-	ModelPatchNode* modelPatchNode_) // Self
+Instance::Instance(
+	const char* name, SceneGraph* scene)
 	:	SceneNode(name, scene),
-		MoveComponent(this),
-		SpatialComponent(this, &obb),
-		modelPatchNode(modelPatchNode_)
+		MoveComponent(this)
 {
-	sceneNodeProtected.moveC = this;
-
-	// Dont mark it as spatial because it's sub-spatial and don't want to 
-	// be updated by the scene
-	sceneNodeProtected.spatialC = nullptr;
-
-	ANKI_ASSERT(modelPatchNode);
-}
-
-//==============================================================================
-void ModelPatchNodeInstance::moveUpdate()
-{
-	ANKI_ASSERT(modelPatchNode);
-
-	// Update the obb of self
-	obb = modelPatchNode->modelPatch->getBoundingShape().getTransformed(
-		getWorldTransform());
-	SpatialComponent::markForUpdate();
-
-	// If this instance is the last update the parent's collision shape
-	ANKI_ASSERT(modelPatchNode->instances.size() > 0);
-	if(this == modelPatchNode->instances.back())
-	{
-		modelPatchNode->updateSpatialCs();
-	}
+	addComponent(static_cast<MoveComponent*>(this));
 }
 
 //==============================================================================
@@ -102,6 +75,20 @@ ModelPatchNode::~ModelPatchNode()
 	}
 }
 
+//==============================================================================
+void ModelPatchNode::getRenderingData(
+	const PassLodKey& key, 
+	const Vao*& vao, const ShaderProgram*& prog,
+	const U32* subMeshIndicesArray, U subMeshIndicesCount,
+	Drawcall& dracall)
+{
+	drawcall.prim
+
+	modelPatch->getRenderingDataSub(key, vao, prog, 
+		subMeshIndicesArray, subMeshIndicesCount, 
+		indicesCountArray, indicesOffsetArray, drawcallCount);
+}
+
 //==============================================================================
 const Transform* ModelPatchNode::getRenderWorldTransforms()
 {

+ 4 - 4
src/scene/RenderComponent.cpp

@@ -83,9 +83,9 @@ RenderComponentVariable::~RenderComponentVariable()
 
 //==============================================================================
 RenderComponent::RenderComponent(SceneNode* node)
-	: SceneComponent(this), vars(node->getSceneAllocator())
+	: SceneComponent(this, node), vars(node->getSceneAllocator())
 {
-	init(*node);
+	init();
 }
 
 //==============================================================================
@@ -101,9 +101,9 @@ RenderComponent::~RenderComponent()
 }
 
 //==============================================================================
-void RenderComponent::init(SceneNode& node)
+void RenderComponent::init()
 {
-	const Material& mtl = getMaterial(node);
+	const Material& mtl = getMaterial();
 
 	// Create the material variables using a visitor
 	CreateNewRenderComponentVariableVisitor vis;

+ 7 - 0
src/scene/SceneNode.cpp

@@ -60,4 +60,11 @@ U32 SceneNode::getLastUpdateFrame() const
 	return max;
 }
 
+//==============================================================================
+void SceneNode::addComponent(SceneComponent* comp)
+{
+	ANKI_ASSERT(comp);
+	components.push_back(comp);
+}
+
 } // end namespace anki

+ 4 - 7
src/scene/SpatialComponent.cpp

@@ -4,13 +4,10 @@
 namespace anki {
 
 //==============================================================================
-SpatialComponent::SpatialComponent(SceneNode* node, const CollisionShape* cs,
-	U32 flags)
+SpatialComponent::SpatialComponent(SceneNode* node, U32 flags)
 	:	SceneComponent(this, node),
-		Bitset<U8>(flags),
-		spatialCs(cs)
+		Bitset<U8>(flags)
 {
-	ANKI_ASSERT(spatialCs);
 	markForUpdate();
 }
 
@@ -19,7 +16,7 @@ SpatialComponent::~SpatialComponent()
 {}
 
 //==============================================================================
-Bool SpatialComponent::update(SceneNode&, F32, F32, UpdateType updateType)
+Bool SpatialComponent::update(SceneNode&, F32, F32, UpdateType uptype)
 {
 	Bool updated = false;
 
@@ -28,7 +25,7 @@ Bool SpatialComponent::update(SceneNode&, F32, F32, UpdateType updateType)
 		updated = bitsEnabled(SF_MARKED_FOR_UPDATE);
 		if(updated)
 		{
-			spatialCs->toAabb(aabb);
+			getSpatialCollisionShape().toAabb(aabb);
 			disableBits(SF_MARKED_FOR_UPDATE);
 		}
 	}