Ver Fonte

Added a way for components to get notified when parent scene object changes

BearishSun há 10 anos atrás
pai
commit
ea11bee3c1

+ 7 - 0
BansheeCore/Include/BsComponent.h

@@ -80,6 +80,12 @@ namespace BansheeEngine
 		/**	Called when the component is activated or created. */
 		virtual void onEnabled() {}
 
+		/** Checks whether the component wants to received the specified transform changed message. */
+		bool supportsNotify(TransformChangedFlags flags) const { return (mNotifyFlags & flags) != 0; }
+
+		/** Notifies the component that its parent scene object has changed. */
+		virtual void notifyTransformChanged(TransformChangedFlags flags) { }
+
 		/**
 		 * Destroys this component.
 		 *
@@ -95,6 +101,7 @@ namespace BansheeEngine
 
 	protected:
 		HSceneObject mParent;
+		TransformChangedFlags mNotifyFlags;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/

+ 8 - 0
BansheeCore/Include/BsGameObject.h

@@ -26,6 +26,14 @@ namespace BansheeEngine
 
 	typedef std::shared_ptr<GameObjectInstanceData> GameObjectInstanceDataPtr;
 
+	/** Flags used for notifying child scene object and components when a transform has been changed. */
+	enum TransformChangedFlags
+	{
+		TCF_None = 0x00,
+		TCF_Transform = 0x01,
+		TCF_Parent = 0x02
+	};
+
 	/** @endcond */
 
 	/**

+ 6 - 2
BansheeCore/Include/BsSceneObject.h

@@ -345,8 +345,12 @@ namespace BansheeEngine
 		mutable UINT32 mDirtyFlags;
 		mutable UINT32 mDirtyHash;
 
-		/** Marks the transform as dirty so that we know to update it when the transform is requested. */
-		void markTfrmDirty() const;
+		/** 
+		 * Notifies components and child scene object that a transform has been changed.  
+		 * 
+		 * @param	flags	Specifies in what way was the transform changed.
+		 */
+		void notifyTransformChanged(TransformChangedFlags flags) const;
 
 		/** Updates the local transform. Normally just reconstructs the transform matrix from the position/rotation/scale. */
 		void updateLocalTfrm() const;

+ 1 - 1
BansheeCore/Source/BsComponent.cpp

@@ -7,7 +7,7 @@
 namespace BansheeEngine
 {
 	Component::Component(const HSceneObject& parent)
-		:mParent(parent)
+		:mParent(parent), mNotifyFlags(TCF_None)
 	{
 		setName("Component");
 	}

+ 14 - 10
BansheeCore/Source/BsSceneObject.cpp

@@ -238,19 +238,19 @@ namespace BansheeEngine
 	void SceneObject::setPosition(const Vector3& position)
 	{
 		mPosition = position;
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	void SceneObject::setRotation(const Quaternion& rotation)
 	{
 		mRotation = rotation;
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	void SceneObject::setScale(const Vector3& scale)
 	{
 		mScale = scale;
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	void SceneObject::setWorldPosition(const Vector3& position)
@@ -269,7 +269,7 @@ namespace BansheeEngine
 		else
 			mPosition = position;
 
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	void SceneObject::setWorldRotation(const Quaternion& rotation)
@@ -283,7 +283,7 @@ namespace BansheeEngine
 		else
 			mRotation = rotation;
 
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	void SceneObject::setWorldScale(const Vector3& scale)
@@ -306,7 +306,7 @@ namespace BansheeEngine
 		else
 			mScale = scale;
 
-		markTfrmDirty();
+		notifyTransformChanged(TCF_Transform);
 	}
 
 	const Vector3& SceneObject::getWorldPosition() const
@@ -424,15 +424,19 @@ namespace BansheeEngine
 			updateWorldTfrm();
 	}
 
-	void SceneObject::markTfrmDirty() const
+	void SceneObject::notifyTransformChanged(TransformChangedFlags flags) const
 	{
 		mDirtyFlags |= DirtyFlags::LocalTfrmDirty | DirtyFlags::WorldTfrmDirty;
 		mDirtyHash++;
 
-		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
+		for(auto& entry : mComponents)
 		{
-			(*iter)->markTfrmDirty();
+			if (entry->supportsNotify(flags))
+				entry->notifyTransformChanged(flags);
 		}
+
+		for (auto& entry : mChildren)
+			entry->notifyTransformChanged(flags);
 	}
 
 	void SceneObject::updateWorldTfrm() const
@@ -535,7 +539,7 @@ namespace BansheeEngine
 				setWorldScale(worldScale);
 			}
 
-			markTfrmDirty();
+			notifyTransformChanged((TransformChangedFlags)(TCF_Parent | TCF_Transform));
 		}
 	}