Changeset 10556

Show
Ignore:
Timestamp:
08/26/09 11:24:02 (5 years ago)
Author:
cedricpinson
Message:

From Michael Platings,
- Animations with equal priority are now weighted correctly relative to each other
- (minor) Channels no longer store their weight as the only time it's used is in update() when Animation can pass in the weight directly
From Cedric Pinson,
- I adjusted the quaternion blending to keep the commutativy property

Location:
OpenSceneGraph/trunk
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osgAnimation/Animation

    r10386 r10556  
    11/*  -*-c++-*-  
    2  *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net> 
     2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> 
    33 * 
    44 * This library is open source and may be redistributed and/or modified under   
     
    7272        float getWeight() const; 
    7373 
    74         bool update (float time); 
     74        bool update (float time, int priority = 0); 
    7575        void resetTargets(); 
    7676 
  • OpenSceneGraph/trunk/include/osgAnimation/Channel

    r10527 r10556  
    3838        virtual Channel* clone() const = 0; 
    3939 
    40         virtual void update(float time) = 0; 
     40        virtual void update(float time, float weight, int priority) = 0; 
    4141        virtual void reset() = 0; 
    4242        virtual Target* getTarget() = 0; 
     
    5252        void setTargetName(const std::string& name); 
    5353 
    54         float getWeight() const; 
    55         void setWeight(float w); 
    56  
    5754        virtual Sampler* getSampler() = 0; 
    5855        virtual const Sampler* getSampler() const = 0; 
     
    6259        std::string _targetName; 
    6360        std::string _name; 
    64         float _weight; 
    6561    }; 
    6662 
     
    9389 
    9490        virtual ~TemplateChannel() {} 
    95         virtual void update(float time)  
     91        virtual void update(float time, float weight, int priority)  
    9692        { 
    9793            // skip if weight == 0 
    98             if (_weight < 1e-4) 
     94            if (weight < 1e-4) 
    9995                return; 
    10096            typename SamplerType::UsingType value; 
    10197            _sampler->getValueAt(time, value); 
    102             _target->update(_weight, value); 
     98            _target->update(weight, value, priority); 
    10399        } 
    104100        virtual void reset() { _target->reset(); } 
  • OpenSceneGraph/trunk/include/osgAnimation/Target

    r10344 r10556  
    3737        virtual ~Target(); 
    3838        virtual void normalize() = 0; 
     39        void reset() { _weight = 0; _priorityWeight = 0; } 
     40        int getCount() const { return referenceCount(); } 
    3941        float getWeight() const { return _weight; } 
    40         void reset() { _weight = 0;} 
    41         int getCount() const { return referenceCount(); } 
    4242    protected: 
    43  
    44         void addWeight(float w) { _weight += w; } 
    4543        float _weight; 
     44        float _priorityWeight; 
     45        int _lastPriority; 
    4646    }; 
    4747 
     
    5555        TemplateTarget(const T& v) { setValue(v); } 
    5656 
    57         void update(float weight, const T& val) 
     57        inline void lerp(float t, const T& a, const T& b); 
     58 
     59        /** 
     60         *  The priority is used to detect a change of priority 
     61         *  It's important to update animation target in priority 
     62         *  order. eg: 
     63         *  all animation with priority 1 
     64         *  all animation with priority 0 
     65         *  all animation with priority -1 
     66         *  ... 
     67         */ 
     68        void update(float weight, const T& val, int priority) 
    5869        { 
    59             if (!_weight) 
    60                 _target = val * weight; 
     70            if (_weight || _priorityWeight) 
     71            { 
     72                if (_lastPriority != priority) 
     73                { 
     74                    // change in priority 
     75                    // add to weight with the same previous priority cumulated weight 
     76                    _weight += _priorityWeight * (1.0 - _weight); 
     77                    _priorityWeight = 0; 
     78                    _lastPriority = priority; 
     79                } 
     80 
     81                _priorityWeight += weight; 
     82                float t = (1.0 - _weight) * weight / _priorityWeight; 
     83                lerp(t, _target, val); 
     84            } 
    6185            else 
    6286            { 
    63                 weight = (1.0 - _weight) * weight; 
    64                 _target += val * weight; 
     87                _priorityWeight = weight; 
     88                _lastPriority = priority; 
     89                _target = val; 
    6590            } 
    66             addWeight(weight); 
    6791        } 
    68         const T& getValue() const { return _target;} 
     92        const T& getValue() const { return _target; } 
    6993 
    70         void normalize() 
    71         { 
    72             float weightSummed = getWeight(); 
    73             if (fabs(weightSummed) < 1e-4 || fabs(weightSummed-1) < 1e-4) 
    74                 return; 
    75             (_target) /= weightSummed; 
    76         } 
     94        inline void normalize(); 
    7795 
    78         void setValue(const T& value) { _target = value;} 
     96        void setValue(const T& value) { _target = value; } 
    7997 
    8098    protected: 
     
    83101    }; 
    84102 
     103    template <class T> 
     104    inline void TemplateTarget<T>::normalize() 
     105    { 
     106        _weight += _priorityWeight * (1.0f - _weight); 
     107        if (_weight < 0.9999f ) 
     108            if (_weight > 0.0001f) 
     109                _target /= _weight; // rescale by default 
     110    } 
    85111 
    86     // Target Specialisation for Quaternions 
     112    template <class T> 
     113    inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b) 
     114    { 
     115        _target = a * (1.0f - t) + b * t; 
     116    } 
     117 
    87118    template <> 
    88     class TemplateTarget< osg::Quat > : public Target 
     119    inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b) 
    89120    { 
    90     public: 
    91              
    92         TemplateTarget () {} 
    93         TemplateTarget (const osg::Quat& q) { setValue(q); } 
    94  
    95         const osg::Quat& getValue() const { return _target;} 
    96         void update(float weight, const osg::Quat& val)  
    97         {  
    98             if (!_weight) 
    99                 _target = val * weight; 
    100             else 
     121        _target = a * (1.0f - t) + b * t; 
     122        osg::Quat::value_type len2 = _target.length2(); 
     123        if ( len2 != 1.0 && len2 != 0.0)  
     124            _target *= 1.0/sqrt(len2); 
     125    } 
     126    template <> 
     127    inline void TemplateTarget<osg::Quat>::normalize() 
     128    { 
     129        _weight += _priorityWeight * (1.0f - _weight); 
     130        if (_weight < 0.9999f ) 
     131            if (_weight > 0.0001f) 
    101132            { 
    102                 weight = (1.0 - _weight) * weight; 
    103                 _target += val * weight; 
     133                osg::Quat::value_type len2 = _target.length2(); // normalize 
     134                if ( len2 != 1.0 && len2 != 0.0) 
     135                    _target *= 1.0/sqrt(len2); 
    104136            } 
    105             addWeight(weight); 
    106         } 
    107  
    108         // maybe normalize could be non virtual and put on ITarget 
    109         void normalize()  
    110         { 
    111             float weightSummed = getWeight(); 
    112             if (fabs(weightSummed) < 1e-4 || fabs(weightSummed-1.0) < 1e-4) 
    113                 return; 
    114             (_target) /= weightSummed; 
    115         } 
    116  
    117         void setValue(const osg::Quat& value) { _target = value;} 
    118   
    119     protected: 
    120  
    121         osg::Quat _target; 
    122     }; 
     137    } 
    123138   
    124139    typedef TemplateTarget<osg::Quat> QuatTarget; 
  • OpenSceneGraph/trunk/src/osgAnimation/Animation.cpp

    r10393 r10556  
    11/*  -*-c++-*-  
    2  *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net> 
     2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> 
    33 * 
    44 * This library is open source and may be redistributed and/or modified under   
     
    9696} 
    9797 
    98 bool Animation::update (float time) 
     98bool Animation::update (float time, int priority) 
    9999{ 
    100100    if (!_duration) // if not initialized then do it 
     
    139139    for( chan=_channels.begin(); chan!=_channels.end(); ++chan) 
    140140    { 
    141         (*chan)->setWeight(_weight); 
    142         (*chan)->update(t); 
     141        (*chan)->update(t, _weight, priority); 
    143142    } 
    144143    return true; 
  • OpenSceneGraph/trunk/src/osgAnimation/BasicAnimationManager.cpp

    r9877 r10556  
    11/*  -*-c++-*-  
    2  *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net> 
     2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> 
    33 * 
    44 * This library is open source and may be redistributed and/or modified under   
     
    9191        // update all animation 
    9292        std::vector<int> toremove; 
     93        int priority = iterAnim->first; 
    9394        AnimationList& list = iterAnim->second; 
    9495        for (unsigned int i = 0; i < list.size(); i++) 
    9596        { 
    96             if (! list[i]->update(time))  
     97            if (! list[i]->update(time, priority))  
    9798            { 
    9899                // debug 
  • OpenSceneGraph/trunk/src/osgAnimation/Channel.cpp

    r10386 r10556  
    11/*  -*-c++-*-  
    2  *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net> 
     2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> 
    33 * 
    44 * This library is open source and may be redistributed and/or modified under   
     
    1616using namespace osgAnimation; 
    1717 
    18 Channel::Channel() { _weight=1; } 
     18Channel::Channel() {} 
    1919Channel::~Channel() {} 
    2020Channel::Channel(const Channel& channel) : osg::Referenced(channel), 
    2121                                           _targetName(channel._targetName), 
    22                                            _name(channel._name), 
    23                                            _weight(channel._weight) 
     22                                           _name(channel._name) 
    2423{ 
    2524} 
     
    3029const std::string& Channel::getTargetName() const { return _targetName;} 
    3130void Channel::setTargetName (const std::string& name) { _targetName = name; } 
    32  
    33 float Channel::getWeight() const { return _weight;} 
    34 void Channel::setWeight(float w) { _weight = w;} 
    35  
  • OpenSceneGraph/trunk/src/osgAnimation/MorphGeometry.cpp

    r10518 r10556  
    203203} 
    204204 
    205 UpdateMorph::UpdateMorph(const UpdateMorph& apc,const osg::CopyOp& copyop) : AnimationUpdateCallback<osg::NodeCallback>(apc, copyop) 
     205UpdateMorph::UpdateMorph(const UpdateMorph& apc,const osg::CopyOp& copyop) :  
     206    osg::Object(apc, copyop), 
     207    AnimationUpdateCallback<osg::NodeCallback>(apc, copyop) 
    206208{ 
    207209} 
     
    272274    else 
    273275  { 
    274       std::cerr << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << std::endl; 
     276      osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << std::endl; 
    275277  } 
    276278  return false; 
  • OpenSceneGraph/trunk/src/osgAnimation/Target.cpp

    r9093 r10556  
    11/*  -*-c++-*-  
    2  *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net> 
     2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> 
    33 * 
    44 * This library is open source and may be redistributed and/or modified under   
     
    1919using namespace osgAnimation; 
    2020 
    21 Target::Target() { reset();} 
     21Target::Target() : _weight(0), _priorityWeight(0), _lastPriority(0) {} 
    2222Target::~Target() {} 
  • OpenSceneGraph/trunk/src/osgPlugins/osgAnimation/ReaderWriter.cpp

    r10518 r10556  
    147147    pChannel->setTargetName(target); 
    148148 
     149// we dont need this info 
    149150    float weight = 1.0; 
    150151    if (fr.matchSequence("weight %f"))  
     
    154155        iteratorAdvanced = true; 
    155156    } 
    156     pChannel->setWeight(weight); 
     157//    pChannel->setWeight(weight); 
    157158    return iteratorAdvanced; 
    158159} 
     
    547548    fw.indent() << "target \"" << pChannel->getTargetName() << "\"" << std::endl; 
    548549 
    549     fw.indent() << "weight " << pChannel->getWeight() << std::endl; 
     550//    fw.indent() << "weight " << pChannel->getWeight() << std::endl; 
    550551 
    551552    ContainerType* kfc  = pChannel->getSamplerTyped()->getKeyframeContainerTyped();