Kaynağa Gözat

Adds crossfade(AnimationClip* clip, unsigned long duration) to AnimationClip.
Adds setBlendWeight()/getBlendWeight() to AnimationClip.
Fixes bug with default clip. Default clip now lazily created when needed (ie: first call to getClip()/play())
Added time stamping to AnimationClip's so their timings are more accurate.

Kieran Cunney 14 yıl önce
ebeveyn
işleme
e73ccb544e

+ 4 - 0
gameplay/src/Animation.cpp

@@ -56,6 +56,10 @@ Animation::~Animation()
         }
         _clips->clear();
     }
+
+    SAFE_DELETE(_clips);
+
+    SAFE_DELETE(_defaultClip);
 }
 
 Animation::Channel::Channel(AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)

+ 2 - 2
gameplay/src/Animation.h

@@ -170,8 +170,8 @@ private:
     std::string _id;                        // The Animation's ID.
     unsigned long _duration;                // the length of the animation (in milliseconds).
     std::vector<Channel*> _channels;        // The channels within this Animation.
-    AnimationClip* _defaultClip;
-    std::vector<AnimationClip*>* _clips;     // All the clips created from this Animation.
+    AnimationClip* _defaultClip;            // The Animation's default clip.
+    std::vector<AnimationClip*>* _clips;    // All the clips created from this Animation.
 
 };
 

+ 36 - 42
gameplay/src/AnimationClip.cpp

@@ -46,6 +46,8 @@ AnimationClip::~AnimationClip()
         valueIter++;
     }
 
+    SAFE_DELETE(_crossFadeToClip);
+    SAFE_DELETE(_channelPriority);
     SAFE_DELETE(_beginListeners);
     SAFE_DELETE(_endListeners);
 }
@@ -161,36 +163,37 @@ void AnimationClip::stop()
 
 void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
 {
-    if (_isPlaying)
+    assert(clip);
+
+    if (clip->_isPlaying && clip->_isFadingOut)
     {
-        if (clip->_isPlaying && clip->_isFadingOut)
-        {
-            clip->_crossFadeToClip->_isFadingIn = false;
-            SAFE_RELEASE(clip->_crossFadeToClip);
-        }
+        clip->_isFadingOut = false;
+        clip->_crossFadeToClip->_isFadingIn = false;
+        SAFE_RELEASE(clip->_crossFadeToClip);
+    }
 
-        // If I already have a clip I'm fading too.. release it.
-        // What about if it's currently playing? Should I stop it?
-        if (_crossFadeToClip)
-            SAFE_RELEASE(_crossFadeToClip);
+    // If I already have a clip I'm fading too.. release it.
+    if (_crossFadeToClip)
+        SAFE_RELEASE(_crossFadeToClip);
 
-        // Assign the clip we're fading to, and increase its ref count.
-        _crossFadeToClip = clip;
-        _crossFadeToClip->addRef();
+    // Assign the clip we're fading to, and increase its ref count.
+    _crossFadeToClip = clip;
+    _crossFadeToClip->addRef();
         
-        // Set the fade in clip to fading in, and set the duration of the fade in.
-        _crossFadeToClip->_isFadingIn = true;
+    // Set the fade in clip to fading in, and set the duration of the fade in.
+    _crossFadeToClip->_isFadingIn = true;
     
-        // Set this clip to fade out, and reset the elapsed time for the fade out.
-        _isFadingOut = true;
-        _crossFadeOutElapsed = 0;
-        _crossFadeOutDuration = duration;
-        _crossFadeStart = (Game::getGameTime() - _timeStarted);
-        _isFadingOutStarted = true;
-    }
+    // Set this clip to fade out, and reset the elapsed time for the fade out.
+    _isFadingOut = true;
+    _crossFadeOutElapsed = 0;
+    _crossFadeOutDuration = duration;
+    _crossFadeStart = (Game::getGameTime() - _timeStarted);
+    _isFadingOutStarted = true;
     
-    _crossFadeToClip->_blendWeight = 1.0f;
-    _crossFadeToClip->play(); // This is going to re-start animations anyways..
+    if (!_isPlaying)
+        play();
+
+    _crossFadeToClip->play(); 
 }
 
 void AnimationClip::addBeginListener(AnimationClip::Listener* listener)
@@ -253,14 +256,14 @@ bool AnimationClip::update(unsigned long elapsedTime)
     
     if (_isFadingOut)
     {
-    
-        if (_isFadingOutStarted) // might be a bug later since this var could go up and down in value.
+        if (_isFadingOutStarted) // Calculate elapsed time since the fade out begin.
         {
             _crossFadeOutElapsed = (_elapsedTime - _crossFadeStart) * speed;
             _isFadingOutStarted = false;
         }
         else
         {
+            // continue tracking elapsed time.
             _crossFadeOutElapsed += elapsedTime * speed;
         }
 
@@ -268,7 +271,8 @@ bool AnimationClip::update(unsigned long elapsedTime)
         {
             float tempBlendWeight = (float) (_crossFadeOutDuration - _crossFadeOutElapsed) / (float) _crossFadeOutDuration;
             _crossFadeToClip->_blendWeight = (1.0f - tempBlendWeight);
-                
+            
+            // adjust the clip your blending to's weight to be a percentage of your current blend weight
             if (_isFadingIn)
             {
                 _crossFadeToClip->_blendWeight *= _blendWeight;
@@ -280,7 +284,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
             }
         }
         else
-        {
+        {   // Fade done.
             _crossFadeToClip->_blendWeight = 1.0f;
                 
             if (_isFadingIn)
@@ -312,9 +316,6 @@ bool AnimationClip::update(unsigned long elapsedTime)
         if (target->_reassignPriorities)
         {
             _channelPriority[i] = target->getPriority();
-
-            if (target->_nextPriority == target->getActiveAnimationCount())
-                target->_reassignPriorities = false;
         }
 
         if (_blendWeight != 0.0f)
@@ -460,7 +461,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
                     // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
                     Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
 
-                    // Add in contribution.
+                    // Set it to identity.
                     currentQuaternion->setIdentity();
                     
                     // Increase by 4.
@@ -497,10 +498,6 @@ void AnimationClip::onBegin()
     _isPlaying = true;
     _elapsedTime = 0;
 
-    //_blendWeight = 1.0f;
-
-    _isFadingOut = false;
-
     if (_speed > 0)
     {
         _runningTime = 0;
@@ -518,7 +515,7 @@ void AnimationClip::onBegin()
         target = _animation->_channels[i]->_target;
 
         target->increaseActiveAnimationCount();
-        _channelPriority[i] = target->getActiveAnimationCount();
+        _channelPriority[i] = target->getPriority();
     }
 
     // Notify begin listeners.. if any.
@@ -541,12 +538,9 @@ void AnimationClip::onEnd()
     {
         target = _animation->_channels[i]->_target;
         
-        // Reset the channel priority
-        _channelPriority[i] = 0;
-
+        // Decrease active animation count on target and reset the channel priority
         target->decreaseActiveAnimationCount();
-        target->_reassignPriorities = true;
-        target->_nextPriority = 0;
+        _channelPriority[i] = 0;
     }
 
     _blendWeight = 1.0f;

+ 11 - 13
gameplay/src/AnimationClip.h

@@ -196,8 +196,6 @@ public:
      */
     void addEndListener(AnimationClip::Listener* listener);
 
-    void applyBlendWeight(float weight);
-
 private:
 
     /**
@@ -247,18 +245,18 @@ private:
     unsigned long _timeStarted;               // The game time when this clip was actually started.
     unsigned long _elapsedTime;               // Time elapsed while the clip is running.
     long _runningTime;                        // Keeps track of the Animation's relative time in respect to the active duration.
-    unsigned int* _channelPriority;
-    AnimationClip* _crossFadeToClip;
-    unsigned long _crossFadeStart;
-    unsigned long _crossFadeOutElapsed;
-    unsigned long _crossFadeOutDuration;
-    float _blendWeight;
-    bool _isFadingOutStarted;
-    bool _isFadingOut;
-    bool _isFadingIn;
+    unsigned int* _channelPriority;           // Keeps track of each channel's priority.
+    AnimationClip* _crossFadeToClip;          // The clip to cross fade to
+    unsigned long _crossFadeStart;            // The time at which the cross fade started.
+    unsigned long _crossFadeOutElapsed;       // The amount of time that has elapsed for the crossfade.
+    unsigned long _crossFadeOutDuration;      // The duration of the cross fade.
+    float _blendWeight;                       // The clip's blendweight
+    bool _isFadingOutStarted;                 // Flag to indicate if the cross fade started
+    bool _isFadingOut;                        // Flag to indicate if the clip is fading out
+    bool _isFadingIn;                         // Flag to indicate if the clip is fading in.
     std::vector<AnimationValue*> _values;     // AnimationValue holder.
-    std::vector<Listener*>* _beginListeners;
-    std::vector<Listener*>* _endListeners;
+    std::vector<Listener*>* _beginListeners;  // Collection of begin listeners on the clip
+    std::vector<Listener*>* _endListeners;    // Collection of end listeners on the clip
 
 };
 

+ 2 - 0
gameplay/src/AnimationController.cpp

@@ -189,6 +189,7 @@ void AnimationController::update(long elapsedTime)
         return;
 
     std::list<AnimationClip*>::iterator clipIter = _runningClips.begin();
+    unsigned int clipCount = 0;
     while (clipIter != _runningClips.end())
     {
         AnimationClip* clip = (*clipIter);
@@ -201,6 +202,7 @@ void AnimationController::update(long elapsedTime)
         {
             clipIter++;
         }
+        clipCount++;
     }
     
     if (_runningClips.empty())

+ 16 - 8
gameplay/src/AnimationTarget.cpp

@@ -13,7 +13,7 @@ namespace gameplay
 {
 
 AnimationTarget::AnimationTarget()
-    : _targetType(SCALAR), _activeAnimationCount(0), _nextPriority(0), _animations(NULL), _reassignPriorities(false)
+    : _targetType(SCALAR), _activeAnimationCount(0), _currentPriority(0), _animations(NULL), _reassignPriorities(false)
 {
 }
 
@@ -80,22 +80,30 @@ Animation* AnimationTarget::getAnimation(const char* id) const
 
 void AnimationTarget::increaseActiveAnimationCount()
 {
-    _activeAnimationCount++;
+    ++_activeAnimationCount;
 }
 
 void AnimationTarget::decreaseActiveAnimationCount()
 {
-    _activeAnimationCount--;
-}
+    --_activeAnimationCount;
 
-unsigned int AnimationTarget::getActiveAnimationCount() const
-{
-    return _activeAnimationCount;
+    _reassignPriorities = true;
+    _currentPriority = 0;
 }
 
 unsigned int AnimationTarget::getPriority() 
 {
-    return ++_nextPriority;
+    if (_reassignPriorities)
+    {
+        ++_currentPriority;
+
+        if (_currentPriority == _activeAnimationCount)
+            _reassignPriorities = false;
+
+        return _currentPriority;
+    }
+
+    return _activeAnimationCount;
 }
 
 }

+ 4 - 9
gameplay/src/AnimationTarget.h

@@ -115,20 +115,15 @@ private:
      */
     void decreaseActiveAnimationCount();
 
-    /**
-     * Gets the active animation count on target.
-     */
-    unsigned int getActiveAnimationCount() const;
-
     /**
      * Gets the priority to assign to the channel when reassigning priorities.
      */
     unsigned int getPriority();
 
-    unsigned int _activeAnimationCount;
-    bool _reassignPriorities;
-    unsigned int _nextPriority;
-    std::vector<Animation*>* _animations;
+    unsigned int _activeAnimationCount;        // The number of active animations targeting this AnimationTarget.
+    bool _reassignPriorities;                  // A flag to indicate that channel priorities for this AnimationTarget need to be reassigned
+    unsigned int _currentPriority;             // Used to keep track of the current priority when reassigning channel priorities
+    std::vector<Animation*>* _animations;      // Collection of all animations on that target the AnimationTarget
 
 };
 }