Browse Source

Add Grow Functionality

GrowTo allows objects to change size over time.  When the object arrives
at the target size it will perform a callback.
Peter Robinson 10 years ago
parent
commit
e19b7b1dc4

+ 53 - 2
engine/source/2d/sceneobject/SceneObject.cc

@@ -120,7 +120,10 @@ SceneObject::SceneObject() :
     mSceneGroupMask(BIT(mSceneGroup)),
     mSceneGroupMask(BIT(mSceneGroup)),
 
 
     /// Area.
     /// Area.
-    mWorldProxyId(-1),
+	mWorldProxyId(-1),
+
+	// Growing.
+	mGrowActive(false),
 
 
     /// Position / Angle.
     /// Position / Angle.
     mPreTickPosition( 0.0f, 0.0f ),
     mPreTickPosition( 0.0f, 0.0f ),
@@ -553,6 +556,12 @@ void SceneObject::preIntegrate( const F32 totalTime, const F32 elapsedTime, Debu
     // Debug Profiling.
     // Debug Profiling.
     PROFILE_SCOPE(SceneObject_PreIntegrate);
     PROFILE_SCOPE(SceneObject_PreIntegrate);
 
 
+	// Update the Size.
+	if (mGrowActive)
+	{
+		updateSize(elapsedTime);
+	}
+
    // Finish if nothing is dirty.
    // Finish if nothing is dirty.
     if ( !mSpatialDirty )
     if ( !mSpatialDirty )
         return;
         return;
@@ -652,10 +661,19 @@ void SceneObject::postIntegrate(const F32 totalTime, const F32 elapsedTime, Debu
 	{
 	{
 		mFadeActive = false;
 		mFadeActive = false;
 
 
-		PROFILE_SCOPE(SceneObject_onFadeComplete);
+		PROFILE_SCOPE(SceneObject_onFadeToComplete);
 		Con::executef(this, 1, "onFadeToComplete");
 		Con::executef(this, 1, "onFadeToComplete");
 	}
 	}
 
 
+	//Check to see if we're done growing.
+	if (mGrowActive && mSize == mTargetSize)
+	{
+		mGrowActive = false;
+
+		PROFILE_SCOPE(SceneObject_onGrowToComplete);
+		Con::executef(this, 1, "onGrowToComplete");
+	}
+
     // Are we using the sleeping callback?
     // Are we using the sleeping callback?
     if ( mSleepingCallback )
     if ( mSleepingCallback )
     {
     {
@@ -1728,6 +1746,28 @@ bool SceneObject::fadeTo(const ColorF& targetColor, const F32 deltaRed, const F3
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+bool SceneObject::growTo(const Vector2& targetSize, const Vector2& deltaSize)
+{
+	// Check in a scene.
+	if (!getScene())
+	{
+		Con::warnf("SceneObject::fadeTo() - Cannot fade object (%d) to a color as it is not in a scene.", getId());
+		return false;
+	}
+
+	//only set growing active if the target size is not the current size
+	if (targetSize != mSize)
+	{
+		mGrowActive = true;
+		mTargetSize = targetSize;
+		mDeltaSize = deltaSize;
+	}
+
+	return true;
+}
+
+//-----------------------------------------------------------------------------
+
 void SceneObject::cancelMoveTo( const bool autoStop )
 void SceneObject::cancelMoveTo( const bool autoStop )
 {
 {
     // Only cancel an active moveTo event
     // Only cancel an active moveTo event
@@ -4165,6 +4205,17 @@ void SceneObject::updateBlendColor(const F32 elapsedTime)
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+void SceneObject::updateSize(const F32 elapsedTime)
+{
+	// Apply the size deltas to the area to move it toward the targetSize.
+	mSize.x = processEffect(mSize.x, mTargetSize.x, mDeltaSize.x * elapsedTime);
+	mSize.y = processEffect(mSize.y, mTargetSize.y, mDeltaSize.y * elapsedTime);
+
+	setSize(mSize);
+}
+
+//-----------------------------------------------------------------------------
+
 F32 SceneObject::processEffect(const F32 current, const F32 target, const F32 rate)
 F32 SceneObject::processEffect(const F32 current, const F32 target, const F32 rate)
 {
 {
 	if (mFabs(current - target) < rate)
 	if (mFabs(current - target) < rate)

+ 12 - 1
engine/source/2d/sceneobject/SceneObject.h

@@ -143,7 +143,12 @@ protected:
     b2AABB                  mCurrentAABB;
     b2AABB                  mCurrentAABB;
     Vector2                 mLocalSizeOOBB[4];
     Vector2                 mLocalSizeOOBB[4];
     Vector2                 mRenderOOBB[4];
     Vector2                 mRenderOOBB[4];
-    S32                     mWorldProxyId;
+	S32                     mWorldProxyId;
+
+	// Growing
+	bool					mGrowActive;
+	Vector2					mTargetSize;
+	Vector2					mDeltaSize;
 
 
     /// Position / Angle.
     /// Position / Angle.
     Vector2                 mPreTickPosition;
     Vector2                 mPreTickPosition;
@@ -412,6 +417,12 @@ public:
 	inline bool				isFadeToComplete( void ) const				{ return !mFadeActive; }
 	inline bool				isFadeToComplete( void ) const				{ return !mFadeActive; }
 	void					updateBlendColor( const F32 elapsedTime );
 	void					updateBlendColor( const F32 elapsedTime );
 
 
+	// Grow to
+	bool					growTo( const Vector2& targetSize, const Vector2& deltaSize );
+	inline void				cancelGrowTo(void)							{ mGrowActive = false; }
+	inline bool				isGrowToComplete(void) const				{ return !mGrowActive; }
+	void					updateSize(const F32 elapsedTime);
+
     /// Force and impulse.
     /// Force and impulse.
     void                    applyForce( const Vector2& worldForce, const bool wake = true );
     void                    applyForce( const Vector2& worldForce, const bool wake = true );
     void                    applyForce( const Vector2& worldForce, const Vector2& worldPoint, const bool wake = true);
     void                    applyForce( const Vector2& worldForce, const Vector2& worldPoint, const bool wake = true);

+ 117 - 0
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -2042,6 +2042,103 @@ ConsoleMethodWithDocs(SceneObject, fadeToTime, ConsoleBool, 4, 4, (targetColor r
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+/*! Grows or shrinks the object to the target size.
+	The current size of the object will continue to change until it arrives at the target size or the grow is cancelled.
+	The change will continue even if the size is set directly.
+	@param (width / height) The target size to grow or shrink the object to.
+	@param (rateX / rateY) The rate per second to change the size. Must be a number greater than zero even if shrinking. Can be one or two values.
+	@return Whether the grow started or not.
+*/
+ConsoleMethodWithDocs(SceneObject, growTo, ConsoleBool, 4, 4, (targetSize width / height, rate rateX / rateY))
+{
+	if (argc < 3)
+	{
+		Con::warnf("Scene::growTo() - Invalid number of parameters!");
+		return false;
+	}
+
+	const U32 targetCount = Utility::mGetStringElementCount(argv[2]);
+	if (targetCount != 2)
+	{
+		Con::warnf("Scene::growTo() - Invalid size! Target size requires two values (width / height)!");
+		return false;
+	}
+
+	Vector2 rate;
+	const U32 rateCount = Utility::mGetStringElementCount(argv[2]);
+	if (rateCount == 1)
+	{
+		rate.x = dAtof(Utility::mGetStringElement(argv[3], 0));
+		rate.y = rate.x;
+	}
+	else if (rateCount == 2)
+	{
+		rate.x = dAtof(Utility::mGetStringElement(argv[3], 0));
+		rate.y = dAtof(Utility::mGetStringElement(argv[3], 1));
+	}
+	else
+	{
+		Con::warnf("Scene::growTo() - Invalid size! Target size requires two values (width / height)!");
+		return false;
+	}
+
+	if (rate.x <= 0.0f || rate.y <= 0.0f)
+	{
+		Con::warnf("Scene::growTo() - Rate must be greater than zero!");
+		return false;
+	}
+
+	return object->growTo(Vector2(dAtof(Utility::mGetStringElement(argv[2], 0)),
+		dAtof(Utility::mGetStringElement(argv[2], 1))),
+		rate);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Grows or shrinks the object to the target size over a period of time.
+	The current size of the object will continue to change until it arrives at the target size or the grow is cancelled.
+	The change will continue even if the size is set directly which will change the amount of time it takes.
+	Unhindered, both size values will arrive at the target in approximately the target time.
+	@param (width / height) The target size to grow or shrink the object to.
+	@param time The amount of time in milliseconds that both size values will take to reach the target. Must be a number greater than zero.
+	@return Whether the fade started or not.
+*/
+ConsoleMethodWithDocs(SceneObject, growToTime, ConsoleBool, 4, 4, (targetSize width / height, time))
+{
+	if (argc < 3)
+	{
+		Con::warnf("Scene::growToTime() - Invalid number of parameters!");
+		return false;
+	}
+
+	const U32 targetCount = Utility::mGetStringElementCount(argv[2]);
+	if (targetCount != 2)
+	{
+		Con::warnf("Scene::growToTime() - Invalid size! Target size requires two values (width / height)!");
+		return false;
+	}
+
+	F32 time = dAtof(argv[3]);
+	if (time <= 0.0f)
+	{
+		Con::warnf("Scene::growToTime() - Time must be greater than zero!");
+		return false;
+	}
+
+	// Get the target size values.
+	const F32 tWidth = dAtof(Utility::mGetStringElement(argv[2], 0));
+	const F32 tHeight = dAtof(Utility::mGetStringElement(argv[2], 1));
+
+	// Get the rate to change each value. The rate will be change per second.
+	const Vector2 currentSize = object->getSize();
+	F32 rWidth = (1000.0f * fabs(tWidth - currentSize.x)) / time;
+	F32 rHeight = (1000.0f * fabs(tHeight - currentSize.y)) / time;
+
+	return object->growTo(Vector2(tWidth, tHeight), Vector2(rWidth, rHeight));
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Stop a previous 'moveTo' command.
 /*! Stop a previous 'moveTo' command.
     @param autoStop? - Whether to automatically set the linear velocity to zero or not
     @param autoStop? - Whether to automatically set the linear velocity to zero or not
     @return No return value.
     @return No return value.
@@ -2090,6 +2187,16 @@ ConsoleMethodWithDocs(SceneObject, cancelFadeTo, ConsoleVoid, 2, 2, ())
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+/*! Stop a previous 'growTo' command.
+	@return No return value.
+*/
+ConsoleMethodWithDocs(SceneObject, cancelGrowTo, ConsoleVoid, 2, 2, ())
+{
+	object->cancelGrowTo();
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Gets whether a previous 'moveTo' command has completed or not.
 /*! Gets whether a previous 'moveTo' command has completed or not.
     @return No return value.
     @return No return value.
 */
 */
@@ -2120,6 +2227,16 @@ ConsoleMethodWithDocs(SceneObject, isFadeToComplete, ConsoleBool, 2, 2, ())
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+/*! Gets whether a previous 'growTo' command has completed or not.
+	@return No return value.
+*/
+ConsoleMethodWithDocs(SceneObject, isGrowToComplete, ConsoleBool, 2, 2, ())
+{
+	return object->isGrowToComplete();
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Applies a force at a world point.
 /*! Applies a force at a world point.
     If the force is not applied at the center of mass, it will generate a torque and affect the angular velocity.
     If the force is not applied at the center of mass, it will generate a torque and affect the angular velocity.
     @param worldForceX/Y - The world force vector in Newtons (N).
     @param worldForceX/Y - The world force vector in Newtons (N).