Просмотр исходного кода

Scene refactoring. WONT COMPILE

Panagiotis Christopoulos Charitos 12 лет назад
Родитель
Сommit
2dfe7d7ec8

+ 11 - 0
include/anki/scene/Camera.h

@@ -46,6 +46,17 @@ public:
 	virtual F32 getFar() const = 0;
 	/// @}
 
+	/// @name SceneNode virtuals
+	/// @{
+	void componentUpdated(SceneComponent& comp)
+	{
+		if(comp.getId() == SceneComponent::getVariadicTypeId<MoveComponent>())
+		{
+			moveUpdate(static_cast<MoveComponent&>(comp));
+		}
+	}
+	/// @}
+
 	void lookAtPoint(const Vec3& point);
 
 protected:

+ 36 - 16
include/anki/scene/FrustumComponent.h

@@ -37,27 +37,48 @@ public:
 	{
 		return *frustum;
 	}
+	Frustum& getFrustum()
+	{
+		return *frustum;
+	}
 
 	const Mat4& getProjectionMatrix() const
 	{
 		return projectionMat;
 	}
+	void setProjectionMatrix(const Mat4& m)
+	{
+		projectionMat = m;
+	}
 
 	const Mat4& getViewMatrix() const
 	{
 		return viewMat;
 	}
+	void setViewMatrix(const Mat4& m)
+	{
+		viewMat = m;
+	}
 
 	const Mat4& getViewProjectionMatrix() const
 	{
 		return viewProjectionMat;
 	}
+	void setViewProjectionMatrix(const Mat4& m)
+	{
+		viewProjectionMat = m;
+	}
 
 	/// Get the origin for sorting and visibility tests
-	const Vec3& getFrustumOrigin() const
+	const Vec3& getOrigin() const
 	{
 		return origin;
 	}
+	/// You need to mark it for update after calling this
+	void setOrigin(const Vec3& ori)
+	{
+		origin = ori;
+	}
 
 	void setVisibilityTestResults(VisibilityTestResults* visible_)
 	{
@@ -91,11 +112,18 @@ public:
 
 	/// @name SceneComponent overrides
 	/// @{
-	Bool update(SceneNode&, F32, F32)
+	Bool update(SceneNode&, F32, F32, UpdateType updateType)
 	{
-		Bool out = markedForUpdate;
-		markedForUpdate = false;
-		return out;
+		if(updateType == ASYNC_UPDATE)
+		{
+			Bool out = markedForUpdate;
+			markedForUpdate = false;
+			return out;
+		}
+		else
+		{
+			return false;
+		}
 	}
 
 	void reset()
@@ -103,27 +131,19 @@ public:
 		visible = nullptr;
 	}
 	/// @}
-
-protected:
+private:
 	Frustum* frustum = nullptr;
 	Mat4 projectionMat = Mat4::getIdentity();
 	Mat4 viewMat = Mat4::getIdentity();
 	Mat4 viewProjectionMat = Mat4::getIdentity();
 
-	/// You need to mark it for update after calling this
-	void setOrigin(const Vec3& ori)
-	{
-		origin = ori;
-	}
+	/// A cached value
+	Vec3 origin;
 
-private:
 	/// 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;
 
-	/// A cached value
-	Vec3 origin;
-
 	Bool8 markedForUpdate;
 };
 /// @}

+ 4 - 6
include/anki/scene/MoveComponent.h

@@ -88,7 +88,7 @@ public:
 	/// @note Don't update if child because we start from roots and go to
 	///       children and we don't want a child to be updated before the
 	///       parent
-	Bool update(SceneNode&, F32, F32);
+	Bool update(SceneNode&, F32, F32, UpdateType uptype);
 	/// @}
 
 	/// @name Mess with the local transform
@@ -133,11 +133,6 @@ public:
 	}
 	/// @}
 
-	/// This is called by the @a update() method only when the object had
-	/// actually moved. It's overridable
-	virtual void moveUpdate()
-	{}
-
 private:
 	/// The transformation in local space
 	Transform lTrf = Transform::getIdentity();
@@ -149,6 +144,9 @@ private:
 	/// Keep the previous transformation for checking if it moved
 	Transform prevWTrf = Transform::getIdentity();
 
+	/// Hold the node
+	SceneNode* node;
+
 	void markForUpdate()
 	{
 		enableBits(MF_MARKED_FOR_UPDATE);

+ 20 - 15
include/anki/scene/SceneComponent.h

@@ -30,6 +30,17 @@ typedef VisitableCommonBase<
 class SceneComponent: public SceneComponentVisitable
 {
 public:
+	/// The update type
+	enum UpdateType
+	{
+		/// The update happens in the thread safe sync section
+		SYNC_UPDATE, 
+		
+		/// The update happens in a thread. This should not touch data that 
+		/// belong to other nodes
+		ASYNC_UPDATE 
+	};
+
 	/// Construct the scene component. The x is bogus
 	template<typename T>
 	SceneComponent(const T* x)
@@ -41,34 +52,28 @@ public:
 	virtual void reset()
 	{}
 
-	/// Do some updating on the thread safe sync section
-	/// @return true if an update happened
-	virtual Bool syncUpdate(SceneNode& node, F32 prevTime, F32 crntTime)
-	{
-		return false;
-	}
-
 	/// Do some updating
 	/// @return true if an update happened
-	virtual Bool update(SceneNode& node, F32 prevTime, F32 crntTime)
+	virtual Bool update(SceneNode& node, F32 prevTime, F32 crntTime, 
+		UpdateType updateType)
 	{
 		return false;
 	}
 
 	/// Called only by the SceneGraph
-	void updateReal(SceneNode& node, F32 prevTime, F32 crntTime)
-	{
-		if(update(node, prevTime, crntTime))
-		{
-			timestamp = getGlobTimestamp();
-		}
-	}
+	Bool updateReal(SceneNode& node, F32 prevTime, F32 crntTime,
+		UpdateType updateType);
 
 	Timestamp getTimestamp() const
 	{
 		return timestamp;
 	}
 
+	I getId() const
+	{
+		return getVisitableTypeId();
+	}
+
 protected:
 	Timestamp timestamp;
 };

+ 32 - 100
include/anki/scene/SceneNode.h

@@ -10,15 +10,6 @@ namespace anki {
 
 class SceneGraph; // Don't include
 
-// Components forward. Don't include
-class MoveComponent;
-class RenderComponent;
-class FrustumComponent;
-class SpatialComponent;
-class Light;
-class RigidBody;
-class Path;
-
 /// @addtogroup Scene
 /// @{
 
@@ -26,6 +17,13 @@ class Path;
 class SceneNode
 {
 public:
+	/// Scene node update type
+	enum UpdateType
+	{
+		SYNC_UPDATE,
+		ASYNC_UPDATE
+	};
+
 	/// @name Constructors/Destructor
 	/// @{
 
@@ -61,88 +59,25 @@ public:
 	}
 	/// @}
 
-	/// @name Accessors of components
-	/// @{
-	MoveComponent* getMoveComponent()
-	{
-		return sceneNodeProtected.moveC;
-	}
-	const MoveComponent* getMoveComponent() const
-	{
-		return sceneNodeProtected.moveC;
-	}
-
-	RenderComponent* getRenderComponent()
-	{
-		return sceneNodeProtected.renderC;
-	}
-	const RenderComponent* getRenderComponent() const
-	{
-		return sceneNodeProtected.renderC;
-	}
-
-	FrustumComponent* getFrustumComponent()
-	{
-		return sceneNodeProtected.frustumC;
-	}
-	const FrustumComponent* getFrustumComponent() const
-	{
-		return sceneNodeProtected.frustumC;
-	}
-
-	SpatialComponent* getSpatialComponent()
-	{
-		return sceneNodeProtected.spatialC;
-	}
-	const SpatialComponent* getSpatialComponent() const
-	{
-		return sceneNodeProtected.spatialC;
-	}
-
-	Light* getLight()
-	{
-		return sceneNodeProtected.lightC;
-	}
-	const Light* getLight() const 
-	{
-		return sceneNodeProtected.lightC;
-	}
-
-	RigidBody* getRigidBody()
-	{
-		return sceneNodeProtected.rigidBodyC;
-	}
-	const RigidBody* getRigidBody() const 
-	{
-		return sceneNodeProtected.rigidBodyC;
-	}
-
-	Path* getPath()
-	{
-		return sceneNodeProtected.pathC;
-	}
-	const Path* getPath() const 
-	{
-		return sceneNodeProtected.pathC;
-	}
-	/// @}
-
 	/// This is called by the scene every frame after logic and before
 	/// rendering. By default it does nothing
 	/// @param[in] prevUpdateTime Timestamp of the previous update
 	/// @param[in] crntTime Timestamp of this update
-	/// @param[in] frame Frame number
-	virtual void frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
+	/// @param[in] uptype The type of this update
+	virtual void frameUpdate(F32 prevUpdateTime, F32 crntTime, 
+		UpdateType uptype)
 	{
 		(void)prevUpdateTime;
 		(void)crntTime;
-		(void)frame;
+		(void)uptype;
 	}
 
 	/// Called when a component got updated
-	virtual void componentUpdated(SceneComponent& component)
+	virtual void componentUpdated(SceneComponent& component, 
+		SceneComponent::UpdateType uptype)
 	{
 		(void)component;
+		(void)uptype;
 	}
 
 	/// Return the last frame the node was updated. It checks all components
@@ -168,6 +103,16 @@ public:
 		}
 	}
 
+	/// Iterate all components. Const version
+	template<typename Func>
+	void iterateComponents(Func func) const
+	{
+		for(auto comp : components)
+		{
+			func(*comp);
+		}
+	}
+
 	/// Iterate all components of a specific type
 	template<typename Component, typename Func>
 	void iterateComponentsOfType(Func func)
@@ -191,7 +136,7 @@ public:
 		{
 			if(comp->getVisitableTypeId() == id)
 			{
-				return comp;
+				return static_cast<Component*>(comp);
 			}
 		}
 		return nullptr;
@@ -206,7 +151,7 @@ public:
 		{
 			if(comp->getVisitableTypeId() == id)
 			{
-				return comp;
+				return static_cast<Component*>(comp);
 			}
 		}
 		return nullptr;
@@ -231,25 +176,6 @@ public:
 	}
 
 protected:
-	struct
-	{
-		MoveComponent* moveC = nullptr;
-		RenderComponent* renderC = nullptr;
-		FrustumComponent* frustumC = nullptr;
-		SpatialComponent* spatialC = nullptr;
-		Light* lightC = nullptr;
-		RigidBody* rigidBodyC = nullptr;
-		Path* pathC = nullptr;
-	} sceneNodeProtected;
-
-private:
-	SceneGraph* scene = nullptr;
-	SceneString name; ///< A unique name
-	Bool8 markedForDeletion;
-
-protected:
-	SceneVector<SceneComponent*> components;
-
 	/// Create a new component and append it to the components container
 	template<typename T, typename... Args>
 	T* newComponent(Args&&... args)
@@ -263,6 +189,12 @@ protected:
 		components.push_back(comp);
 		return comp;
 	}
+
+private:
+	SceneGraph* scene = nullptr;
+	SceneString name; ///< A unique name
+	SceneVector<SceneComponent*> components;
+	Bool8 markedForDeletion;
 };
 /// @}
 

+ 6 - 33
include/anki/scene/SpatialComponent.h

@@ -5,7 +5,6 @@
 #include "anki/scene/SceneComponent.h"
 #include "anki/Collision.h"
 #include "anki/util/Bitset.h"
-#include "anki/core/Timestamp.h"
 
 namespace anki {
 
@@ -14,14 +13,9 @@ namespace anki {
 
 /// Spatial component for scene nodes. It indicates scene nodes that need to 
 /// be placed in the a sector and they participate in the visibility tests
-class SpatialComponent: 
-	public SceneComponent,
-	public SceneHierarchicalObject<SpatialComponent>, 
-	public Bitset<U8>
+class SpatialComponent: public SceneComponent, public Bitset<U8>
 {
 public:
-	typedef SceneHierarchicalObject<SpatialComponent> Base;
-
 	/// Spatial flags
 	enum SpatialFlag
 	{
@@ -77,34 +71,17 @@ public:
 	}
 
 	/// Used for sorting spatials. In most object the origin is the center of
-	/// the bounding volume but for cameras the origin is the eye point
-	virtual const Vec3& getSpatialOrigin() const
+	/// mess but for cameras the origin is the eye point
+	const Vec3& getOrigin() const
 	{
 		return origin;
 	}
-
-	PtrSize getSubSpatialsCount() const
-	{
-		return getChildrenSize();
-	}
-
-	SpatialComponent& getSubSpatial(PtrSize i)
-	{
-		return getChild(i);
-	}
-	const SpatialComponent& getSubSpatial(PtrSize i) const
+	void setOrigin(const Vec3& o)
 	{
-		return getChild(i);
+		origin = o;
 	}
 	/// @}
 
-	/// Visit this an the rest of the tree spatials
-	template<typename VisitorFunc>
-	void visitSubSpatials(VisitorFunc vis)
-	{
-		Base::visitChildren(vis);
-	}
-
 	/// The derived class has to manually call this method when the collision 
 	/// shape got updated
 	void markForUpdate()
@@ -120,14 +97,10 @@ public:
 	void reset();
 	/// @}
 
-protected:
-	const CollisionShape* spatialCs = nullptr;
-
 private:
+	const CollisionShape* spatialCs = nullptr;
 	Aabb aabb; ///< A faster shape
 	Vec3 origin; ///< Cached value
-
-	void updateInternal();
 };
 /// @}
 

+ 3 - 7
src/scene/Camera.cpp

@@ -11,16 +11,12 @@ Camera::Camera(
 	const char* name, SceneGraph* scene, // SceneNode
 	Frustum* frustum, // SpatialComponent & FrustumComponent
 	CameraType type_) 
-	:	SceneNode(name, scene),
-		MoveComponent(this),
-		SpatialComponent(this, frustum),
-		FrustumComponent(frustum),
-		type(type_)
+	: SceneNode(name, scene), type(type_)
 {
 	// Init components
 	newComponent<MoveComponent>(this);
 	newComponent<SpatialComponent>(this, frustum);
-	newComponent<FrustumComponent>(this, frustum);
+	newComponent<FrustumComponent>(frustum);
 }
 
 //==============================================================================
@@ -61,7 +57,7 @@ void Camera::moveUpdate(MoveComponent& move)
 {
 	// Frustum
 	FrustumComponent& fr = getComponent<FrustumComponent>();
-	fr.setViewMatrix(move.getWorldTransform().getInverse());
+	fr.setViewMatrix(Mat4(move.getWorldTransform().getInverse()));
 	fr.setViewProjectionMatrix(fr.getProjectionMatrix() * fr.getViewMatrix());
 	fr.setOrigin(move.getWorldTransform().getOrigin());
 	fr.markForUpdate();

+ 7 - 7
src/scene/MoveComponent.cpp

@@ -4,10 +4,11 @@
 namespace anki {
 
 //==============================================================================
-MoveComponent::MoveComponent(SceneNode* node, U32 flags)
+MoveComponent::MoveComponent(SceneNode* node_, U32 flags)
 	:	SceneComponent(this),
-		Base(nullptr, node->getSceneAllocator()),
-		Bitset<U8>(flags)
+		Base(nullptr, node_->getSceneAllocator()),
+		Bitset<U8>(flags),
+		node(node_)
 {
 	markForUpdate();
 }
@@ -17,12 +18,11 @@ MoveComponent::~MoveComponent()
 {}
 
 //==============================================================================
-Bool MoveComponent::update(SceneNode&, F32, F32)
+Bool MoveComponent::update(SceneNode&, F32, F32, UpdateType uptype)
 {
-	// Call this only on roots
-	if(getParent() == nullptr)
+	if(uptype == SYNC_UPDATE && getParent() == nullptr)
 	{
-		// If root begin updating
+		// Call this only on roots
 		return updateWorldTransform();
 	}
 

+ 19 - 0
src/scene/SceneComponent.cpp

@@ -0,0 +1,19 @@
+#include "anki/scene/SceneComponent.h"
+#include "anki/scene/SceneNode.h"
+
+namespace anki {
+
+//==============================================================================
+Bool SceneComponent::updateReal(SceneNode& node, F32 prevTime, F32 crntTime,
+	UpdateType updateType)
+{
+	Bool updated = update(node, prevTime, crntTime, updateType);
+	if(updated)
+	{
+		node.componentUpdated(*this, updateType);
+		timestamp = getGlobTimestamp();
+	}
+	return updated;
+}
+
+} // end namespace anki

+ 5 - 18
src/scene/SceneNode.cpp

@@ -10,8 +10,8 @@ namespace anki {
 SceneNode::SceneNode(const char* name_, SceneGraph* scene_)
 	:	scene(scene_),
 		name(getSceneAllocator()),
-		markedForDeletion(false),
-		components(getSceneAllocator())
+		components(getSceneAllocator()),
+		markedForDeletion(false)
 {
 	ANKI_ASSERT(scene);
 
@@ -52,23 +52,10 @@ U32 SceneNode::getLastUpdateFrame() const
 {
 	U32 max = 0;
 
-	const MoveComponent* m = getMoveComponent();
-	if(m && m->getTimestamp() > max)
+	iterateComponents([&](const SceneComponent& comp)
 	{
-		max = m->getTimestamp();
-	}
-
-	const FrustumComponent* fr = getFrustumComponent();
-	if(fr && fr->getTimestamp() > max)
-	{
-		max = fr->getTimestamp();
-	}
-
-	const SpatialComponent* s = getSpatialComponent();
-	if(s && s->getTimestamp() > max)
-	{
-		max = s->getTimestamp();
-	}
+		max = std::max(max, comp.getTimestamp());
+	});
 
 	return max;
 }

+ 5 - 27
src/scene/SpatialComponent.cpp

@@ -7,7 +7,6 @@ namespace anki {
 SpatialComponent::SpatialComponent(SceneNode* node, const CollisionShape* cs,
 	U32 flags)
 	:	SceneComponent(this),
-		Base(nullptr, node->getSceneAllocator()), 
 		Bitset<U8>(flags),
 		spatialCs(cs)
 {
@@ -22,41 +21,20 @@ SpatialComponent::~SpatialComponent()
 //==============================================================================
 Bool SpatialComponent::update(SceneNode&, F32, F32)
 {
-	if(getParent() == nullptr)
-	{
-		visitThisAndChildren([](SpatialComponent& sp)
-		{
-			sp.updateInternal();
-		});	
-	}
-
-	return false;
-}
-
-//==============================================================================
-void SpatialComponent::updateInternal()
-{
-	if(bitsEnabled(SF_MARKED_FOR_UPDATE))
+	Bool needsUpdate = bitsEnabled(SF_MARKED_FOR_UPDATE);
+	if(needsUpdate)
 	{
 		spatialCs->toAabb(aabb);
-		origin = (aabb.getMax() + aabb.getMin()) * 0.5;
-		timestamp = getGlobTimestamp();
-
 		disableBits(SF_MARKED_FOR_UPDATE);
 	}
+
+	return needsUpdate;
 }
 
 //==============================================================================
 void SpatialComponent::reset()
 {
-	// Call this only on roots
-	if(getParent() == nullptr)
-	{
-		visitThisAndChildren([](SpatialComponent& sp)
-		{
-			sp.disableBits(SF_VISIBLE_ANY);
-		});
-	}
+	disableBits(SF_VISIBLE_ANY);
 }
 
 } // end namespace anki