Browse Source

Merge pull request #51 from blackberry-gaming/next-kcunney

Fixes 47.
Sean Paul Taylor 14 years ago
parent
commit
06a3c07437

+ 42 - 23
gameplay/src/Animation.cpp

@@ -31,15 +31,6 @@ Animation::Animation(const char* id, AnimationTarget* target, int propertyId, un
 
 Animation::~Animation()
 {
-    std::vector<Channel*>::iterator channelIter = _channels.begin();
-    
-    while (channelIter != _channels.end())
-    {
-        SAFE_DELETE(*channelIter);
-        channelIter++;
-    }
-    _channels.clear();
-    
     if (_clips != NULL)
     {
         std::vector<AnimationClip*>::iterator clipIter = _clips->begin();
@@ -47,31 +38,42 @@ Animation::~Animation()
         while (clipIter != _clips->end())
         {   
             AnimationClip* clip = *clipIter;
+            clip->stop();
             SAFE_RELEASE(clip);
             clipIter++;
         }
         _clips->clear();
     }
-
     SAFE_DELETE(_clips);
 
     SAFE_DELETE(_defaultClip);
+
+    /*std::vector<Channel*>::iterator channelIter = _channels.begin();
+    while (channelIter != _channels.end())
+    {
+        Animation::Channel* channel = *channelIter;
+        channel->_target->removeChannel(channel);
+        SAFE_RELEASE(channel);
+        channelIter++;
+    }*/
+    _channels.clear();
 }
 
-Animation::Channel::Channel(AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
-    : _isRelative(false)
+Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
+    : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
 {
     // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
-    assert(target->getAnimationPropertyComponentCount(propertyId));
+    assert(_target->getAnimationPropertyComponentCount(propertyId));
+
+    _animation->addRef();
 
-    _target = target;
-    _propertyId = propertyId;
-    _curve = curve;
-    _duration = duration;
+    _target->addChannel(this);
 }
 
 Animation::Channel::~Channel()
 {
+    _animation->removeChannel(this);
+    SAFE_RELEASE(_animation);
     SAFE_DELETE(_curve);
 }
 
@@ -246,10 +248,8 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
 
     SAFE_DELETE(normalizedKeyTimes);
 
-    Channel* channel = new Channel(target, propertyId, curve, duration);
-
+    Channel* channel = new Channel(this, target, propertyId, curve, duration);
     addChannel(channel);
-
     return channel;
 }
 
@@ -295,10 +295,8 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
 
     SAFE_DELETE(normalizedKeyTimes);
 
-    Channel* channel = new Channel(target, propertyId, curve, duration);
-
+    Channel* channel = new Channel(this, target, propertyId, curve, duration);
     addChannel(channel);
-
     return channel;
 }
 
@@ -310,6 +308,27 @@ void Animation::addChannel(Channel* channel)
         _duration = channel->_duration;
 }
 
+void Animation::removeChannel(Channel* channel)
+{
+    std::vector<Animation::Channel*>::iterator itr = _channels.begin();
+    while (itr != _channels.end())
+    {
+        Animation::Channel* chan = *itr;
+        if (channel == chan) 
+        {
+            _channels.erase(itr);
+            itr = _channels.end();
+        }
+        else
+        {
+            itr++;
+        }
+    }
+
+    if (_channels.empty())
+        _controller->destroyAnimation(this);
+}
+
 void Animation::createDefaultClip()
 {
     std::string clipId = _id + ANIMATION_DEFAULT_CLIP_SUFFIX;

+ 8 - 2
gameplay/src/Animation.h

@@ -93,18 +93,19 @@ private:
     {
         friend class AnimationClip;
         friend class Animation;
+        friend class AnimationTarget;
 
     private:
 
-        Channel(AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration);
+        Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration);
         Channel(const Channel& copy);
         ~Channel();
 
+        Animation* _animation;                // Reference to the animation this channel belongs to.
         AnimationTarget* _target;             // The target of this channel.
         int _propertyId;                      // The target property this channel targets.
         Curve* _curve;                        // The curve used to represent the animation data.
         unsigned long _duration;              // The length of the animation (in milliseconds).
-        bool _isRelative;                     // Whether the data should be treated relatively or not. 
     };
 
     /**
@@ -161,6 +162,11 @@ private:
      * Adds a channel to the animation.
      */
     void addChannel(Channel* channel);
+
+    /**
+     * Removes a channel from the animation.
+     */
+    void removeChannel(Channel* channel);
     
     AnimationController* _controller;       // The AnimationController that this Animation will run on.
     std::string _id;                        // The Animation's ID.

+ 20 - 29
gameplay/src/AnimationClip.cpp

@@ -7,7 +7,6 @@
 
 namespace gameplay
 {
-    int AnimationClip::_crazyCounter = 0;
 
 AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
     : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _duration(_endTime - _startTime), _repeatCount(1.0f), 
@@ -29,20 +28,15 @@ AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long
 
 AnimationClip::~AnimationClip()
 {
-    // Explicitly stop this clip if it's currently playing so it gets removed from the controller
-    if (_isPlaying)
-    {
-        stop();
-    }
-
     std::vector<AnimationValue*>::iterator valueIter = _values.begin();
     while (valueIter != _values.end())
     {
         SAFE_DELETE(*valueIter);
         valueIter++;
     }
+    _values.clear();
 
-    SAFE_DELETE(_crossFadeToClip);
+    SAFE_RELEASE(_crossFadeToClip);
     SAFE_DELETE(_channelPriority);
     SAFE_DELETE(_beginListeners);
     SAFE_DELETE(_endListeners);
@@ -308,10 +302,12 @@ bool AnimationClip::update(unsigned long elapsedTime)
         // Get the current value.
         target->getAnimationPropertyValue(channel->_propertyId, value);
 
+        bool isHighest = false;
         // My channel priority has changed if my priority is greater than the active animation count.
-        if (target->_reassignPriorities)
+        if (!target->_highestPriority)
         {
-            _channelPriority[i] = target->getPriority();
+            target->_highestPriority = channel;
+            value->_isFirstActing = true;
         }
 
         if (_blendWeight != 0.0f)
@@ -321,7 +317,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
 
             if (channel->_curve->_quaternionOffsetsCount == 0)
             {
-                if (_channelPriority[i] == 1)
+                if (value->_isFirstActing)
                 {
                     unsigned int componentCount = value->_componentCount;
                     for (unsigned int j = 0; j < componentCount; j++)
@@ -350,7 +346,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
                 unsigned int quaternionOffsetIndex = 0;
                 unsigned int quaternionOffset = 0;
 
-                if (_channelPriority[i] == 1)
+                if (value->_isFirstActing)
                 {
                     do {
                         quaternionOffset = channel->_curve->_quaternionOffsets[quaternionOffsetIndex];
@@ -434,7 +430,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
                 }
             }
         }
-        else if (_channelPriority[i] == 1)
+        else if (value->_isFirstActing)
         {
             if (channel->_curve->_quaternionOffsetsCount == 0)
             {
@@ -503,17 +499,6 @@ void AnimationClip::onBegin()
         _runningTime = _activeDuration;
     }
 
-    AnimationTarget* target = NULL;
-    unsigned int channelCount = _animation->_channels.size();
-    // Sets the starting value.
-    for (unsigned int i = 0; i < channelCount; i++)
-    {
-        target = _animation->_channels[i]->_target;
-
-        target->increaseActiveAnimationCount();
-        _channelPriority[i] = target->getPriority();
-    }
-
     // Notify begin listeners.. if any.
     if (_beginListeners)
     {
@@ -528,15 +513,21 @@ void AnimationClip::onBegin()
 
 void AnimationClip::onEnd()
 {
+    AnimationValue* value;
+    Animation::Channel* channel = NULL;
     AnimationTarget* target = NULL;
     unsigned int channelCount = _animation->_channels.size();
     for (unsigned int i = 0; i < channelCount; i++)
     {
-        target = _animation->_channels[i]->_target;
-        
-        // Decrease active animation count on target and reset the channel priority
-        target->decreaseActiveAnimationCount();
-        _channelPriority[i] = 0;
+        value = _values[i];
+
+        if (value->_isFirstActing)
+        {
+            channel = _animation->_channels[i];
+            target = channel->_target;
+            target->_highestPriority = NULL;
+            value->_isFirstActing = false;
+        }
     }
 
     _blendWeight = 1.0f;

+ 1 - 3
gameplay/src/AnimationClip.h

@@ -27,8 +27,6 @@ public:
      */
     static const unsigned int REPEAT_INDEFINITE = 0;
 
-    static int _crazyCounter;
-
     /**
      * Defines an animation event listener.
      */
@@ -230,7 +228,7 @@ private:
     void onEnd();
 
     std::string _id;                          // AnimationClip ID.
-    Animation* _animation;                    // Animations that this clip plays in parallel.
+    Animation* _animation;                    // The Animation this clip is created from.
     unsigned long _startTime;                 // Start time of the clip.
     unsigned long _endTime;                   // End time of the clip.
     unsigned long _duration;                  // The total duration.

+ 4 - 7
gameplay/src/AnimationController.cpp

@@ -28,9 +28,7 @@ Animation* AnimationController::createAnimation(const char* id, AnimationTarget*
     animation = new Animation(id, target, propertyId, keyCount, keyTimes, keyValues, type);
 
     addAnimation(animation);
-
-    target->addAnimation(animation);
-
+    
     return animation;
 }
 
@@ -46,8 +44,6 @@ Animation* AnimationController::createAnimation(const char* id, AnimationTarget*
 
     addAnimation(animation);
 
-    target->addAnimation(animation);
-
     return animation;
 }
 
@@ -130,6 +126,7 @@ void AnimationController::initialize()
 
 void AnimationController::finalize()
 {
+    stopAllAnimations();
     _state = PAUSED;
 }
 
@@ -218,6 +215,8 @@ void AnimationController::destroyAnimation(Animation* animation)
     {
         if (animation == *itr)
         {
+            Animation* animation = *itr;
+            SAFE_RELEASE(animation);
             _animations.erase(itr);
             return;
         }
@@ -227,8 +226,6 @@ void AnimationController::destroyAnimation(Animation* animation)
 
 void AnimationController::destroyAllAnimations()
 {
-    stopAllAnimations();
-
     std::vector<Animation*>::iterator itr = _animations.begin();
     
     while (itr != _animations.end())

+ 2 - 1
gameplay/src/AnimationController.h

@@ -14,6 +14,7 @@ namespace gameplay
 class AnimationController
 {
     friend class Game;
+    friend class Animation;
     friend class AnimationClip;
 
 public:
@@ -180,7 +181,7 @@ private:
     
     State _state;                               // The current state of the AnimationController.
     std::list<AnimationClip*> _runningClips;    // A list of currently running AnimationClips.
-    std::vector<Animation*> _animations;
+    std::vector<Animation*> _animations;        // A list of animations registered with the AnimationController
 };
 
 }

+ 11 - 78
gameplay/src/AnimationTarget.cpp

@@ -9,97 +9,30 @@ namespace gameplay
 {
 
 AnimationTarget::AnimationTarget()
-    : _targetType(SCALAR), _activeAnimationCount(0), _currentPriority(0), _animations(NULL), _reassignPriorities(false)
+    : _targetType(SCALAR), _highestPriority(NULL), _animationChannels(NULL)
 {
 }
 
 AnimationTarget::~AnimationTarget()
 {
-    if (_animations)
+    if (_animationChannels)
     {
-        std::vector<Animation*>::iterator animationIter = _animations->begin();
-        while (animationIter != _animations->end())
+        std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
+        while (itr != _animationChannels->end())
         {
-            SAFE_RELEASE((*animationIter));
-            animationIter++;
+            SAFE_DELETE((*itr));
+            itr++;
         }
-        SAFE_DELETE(_animations);
+        SAFE_DELETE(_animationChannels);
     }
 }
 
-void AnimationTarget::addAnimation(Animation* animation)
+void AnimationTarget::addChannel(Animation::Channel* channel)
 {
-    if (_animations == NULL)
-    {
-        _animations = new std::vector<Animation*>;
-    }
-
-    _animations->push_back(animation);
-
-    animation->addRef();
-}
-
-unsigned int AnimationTarget::getAnimationCount() const
-{
-    if (_animations)
-        return _animations->size();
-
-    return 0;
-}
-
-Animation* AnimationTarget::getAnimation(unsigned int index) const
-{
-    if (_animations)
-        return _animations->at(index);
-    else
-        return 0;
-}
-
-Animation* AnimationTarget::getAnimation(const char* id) const
-{
-    if (_animations)
-    {
-        std::vector<Animation*>::iterator animationIter = _animations->begin();
-        while(animationIter != _animations->end())
-        {
-            if ((*animationIter)->_id.compare(id) == 0)
-            {
-                return *animationIter;
-            }
-
-            animationIter++;
-        }
-    }
-    
-    return NULL;
-}
-
-void AnimationTarget::increaseActiveAnimationCount()
-{
-    ++_activeAnimationCount;
-}
-
-void AnimationTarget::decreaseActiveAnimationCount()
-{
-    --_activeAnimationCount;
-
-    _reassignPriorities = true;
-    _currentPriority = 0;
-}
-
-unsigned int AnimationTarget::getPriority() 
-{
-    if (_reassignPriorities)
-    {
-        ++_currentPriority;
-
-        if (_currentPriority == _activeAnimationCount)
-            _reassignPriorities = false;
-
-        return _currentPriority;
-    }
+    if (_animationChannels == NULL)
+        _animationChannels = new std::vector<Animation::Channel*>;
 
-    return _activeAnimationCount;
+    _animationChannels->push_back(channel);
 }
 
 }

+ 4 - 46
gameplay/src/AnimationTarget.h

@@ -14,7 +14,7 @@ class AnimationValue;
  * Defines an interface allowing animation to target
  * an object for changing its animation properties.
  */
-class AnimationTarget : public Ref
+class AnimationTarget
 {
     friend class Animation;
     friend class AnimationClip;
@@ -47,31 +47,6 @@ public:
      */
     virtual void setAnimationPropertyValue(int propertyId, AnimationValue* value) = 0;
 
-    /**
-     * Gets the number of Animations on this target.
-     * 
-     * @return The number of Animations targeting this object.
-     */
-    unsigned int getAnimationCount() const;
-
-    /**
-     * Gets the Animation with the given index.
-     * 
-     * @param index The index of the Animation to return.
-     *
-     * @return The Animation at the given index.
-     */
-    Animation* getAnimation(unsigned int index) const;
-
-    /**
-     * Finds the Animation with the given ID.
-     * 
-     * @param id The ID of the Animation to get.
-     * 
-     * @return The Animation with the given ID. NULL if the Animation is not found.
-     */
-    Animation* getAnimation(const char* id) const;
-
 protected:
     
     enum TargetType
@@ -90,7 +65,7 @@ protected:
      */
     virtual ~AnimationTarget();
 
-    void addAnimation(Animation* animation);
+    void addChannel(Animation::Channel* animation);
 
     TargetType _targetType;             // The type of target this is.
 
@@ -101,25 +76,8 @@ private:
      */
     AnimationTarget(const AnimationTarget& copy);
 
-    /**
-     * Increases the active animation count on the target by one.
-     */
-    void increaseActiveAnimationCount();
-
-    /**
-     * Decreases the active animation count on the target by one.
-     */
-    void decreaseActiveAnimationCount();
-
-    /**
-     * Gets the priority to assign to the channel when reassigning priorities.
-     */
-    unsigned int getPriority();
-
-    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
+    Animation::Channel* _highestPriority;
+    std::vector<Animation::Channel*>* _animationChannels;   // Collection of all animation channels that target the AnimationTarget
 
 };
 }

+ 1 - 1
gameplay/src/AnimationValue.cpp

@@ -5,7 +5,7 @@ namespace gameplay
 {
 
 AnimationValue::AnimationValue(unsigned int componentCount)
-  : _componentCount(componentCount), _componentSize(componentCount * sizeof(float))
+  : _isFirstActing(false), _componentCount(componentCount), _componentSize(componentCount * sizeof(float))
 {
     _currentValue = new float[_componentCount];
     _interpolatedValue = new float[_componentCount];

+ 3 - 2
gameplay/src/AnimationValue.h

@@ -72,10 +72,11 @@ private:
      */
     ~AnimationValue();
 
+    bool _isFirstActing;            // Flag indicating if this value's channel is the first to act on the target.
     unsigned int _componentCount;   // The number of float values for the property.
-    unsigned int _componentSize;
+    unsigned int _componentSize;    // The number of bytes of memory the property is.
     float* _currentValue;           // The current value of the property.
-    float* _interpolatedValue;
+    float* _interpolatedValue;      // The last interpolated value of the property.
 };
 
 }

+ 32 - 4
gameplay/src/MaterialParameter.cpp

@@ -302,8 +302,17 @@ unsigned int MaterialParameter::getAnimationPropertyComponentCount(int propertyI
                 case SAMPLER:
                 case METHOD:
                     return 0;
+                case FLOAT:
+                case INT:
+                    return 1;
+                case VECTOR2:
+                    return 2 * _count;
+                case VECTOR3:
+                    return 3 * _count;
+                case VECTOR4:
+                    return 4 * _count;
                 default:
-                    return _count;
+                    return 0;
             }
         }
     }
@@ -326,11 +335,21 @@ void MaterialParameter::getAnimationPropertyValue(int propertyId, AnimationValue
                     value->setFloat(0, _value.intValue);
                     break;
                 case VECTOR2:
+                    for (unsigned int i = 0; i < _count; i++)
+                    {
+                        value->setFloat(_value.floatPtrValue, i * 2, 2);
+                    }
+                    break;
                 case VECTOR3:
+                    for (unsigned int i = 0; i < _count; i++)
+                    {
+                        value->setFloat(_value.floatPtrValue, i * 3, 3);
+                    }
+                    break;
                 case VECTOR4:
                     for (unsigned int i = 0; i < _count; i++)
                     {
-                        value->setFloat(i, _value.floatPtrValue[i]);
+                        value->setFloat(_value.floatPtrValue, i * 4, 4);
                     }
                     break;
 
@@ -355,12 +374,21 @@ void MaterialParameter::setAnimationPropertyValue(int propertyId, AnimationValue
                     _value.intValue = value->getFloat(0);
                     break;
                 case VECTOR2:
+                    for (unsigned int i = 0; i < _count; i++)
+                    {
+                        value->getFloat(_value.floatPtrValue, i * 2, 2);
+                    }
+                    break;
                 case VECTOR3:
+                    for (unsigned int i = 0; i < _count; i++)
+                    {
+                        value->getFloat(_value.floatPtrValue, i * 3, 3);
+                    }
+                    break;
                 case VECTOR4:
-                case MATRIX:
                     for (unsigned int i = 0; i < _count; i++)
                     {
-                        _value.floatPtrValue[i] = value->getFloat(i);
+                        value->getFloat(_value.floatPtrValue, i * 4, 4);
                     }
                     break;
 

+ 1 - 1
gameplay/src/MaterialParameter.h

@@ -27,7 +27,7 @@ namespace gameplay
  * to the Matrix will automatically be reflected in the technique the
  * next time the parameter is applied to the render state.
  */
-class MaterialParameter : public AnimationTarget
+class MaterialParameter : public AnimationTarget, public Ref
 {
     friend class RenderState;
 

+ 1 - 1
gameplay/src/Node.h

@@ -19,7 +19,7 @@ class Scene;
 /**
  * Defines a basic hierachial structure of transformation spaces.
  */
-class Node : public Transform
+class Node : public Transform, public Ref
 {
     friend class Scene;
     friend class Package;