Changeset 9877

Show
Ignore:
Timestamp:
03/09/09 18:38:39 (6 years ago)
Author:
robert
Message:

From Roland Smeenk & Cedric Pinson,

"Summary of changes:
From Roland
-Added MorphGeometry?
-Bone Bindmatrix is only calculated if needed
-osgAnimation plugin now supports all available channel types (before only linear vec3 or quat channels)
-osgAnimation plugin now supports MorphGeometry?
-osgAnimation plugin now supports animation and channel weights, animation playmode, duration and starttime
-removed osgAnimationManager.cpp from CMakeList

From Cedric
-fixed the last_update field (it was only updated at the first update) in BasicAnimationManager?.cpp
- Refactore some part of MorphGeometry? minor changes
- Add osganimationmorph as example
"

Location:
OpenSceneGraph/trunk
Files:
5 added
12 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/CMakeLists.txt

    r9587 r9877  
    116116    ADD_SUBDIRECTORY(osganimationnode) 
    117117    ADD_SUBDIRECTORY(osganimationmakepath) 
     118    ADD_SUBDIRECTORY(osganimationmorph) 
    118119    ADD_SUBDIRECTORY(osganimationskinning) 
    119120    ADD_SUBDIRECTORY(osganimationsolid) 
  • OpenSceneGraph/trunk/include/osgAnimation/Animation

    r9713 r9877  
    7676 
    7777        void setPlaymode (PlayMode mode) { _playmode = mode; } 
     78        PlayMode getPlayMode() const { return _playmode; } 
     79         
    7880        void setStartTime(float time)  { _startTime = time;} 
    7981        float getStartTime() const { return _startTime;} 
  • OpenSceneGraph/trunk/include/osgAnimation/CubicBezier

    r9093 r9877  
    4343        const T& getTangentPoint1() const { return mPoint[1];} 
    4444        const T& getTangentPoint2() const { return mPoint[2];} 
     45         
     46        // steaming operators. 
     47        friend std::ostream& operator << (std::ostream& output, const TemplateCubicBezier<T>& vec) 
     48        { 
     49            output << vec.mPoint[0] << " " 
     50                   << vec.mPoint[1] << " " 
     51                   << vec.mPoint[2]; 
     52            return output; // to enable cascading 
     53        } 
     54 
     55        friend std::istream& operator >> (std::istream& input, TemplateCubicBezier<T>& vec) 
     56        { 
     57            input >> vec.mPoint[0] >> vec.mPoint[1] >> vec.mPoint[2]; 
     58            return input; 
     59        } 
    4560    }; 
    4661 
  • OpenSceneGraph/trunk/include/osgAnimation/Keyframe

    r9093 r9877  
    9999    typedef TemplateKeyframe<float> FloatKeyframe; 
    100100    typedef TemplateKeyframeContainer<float> FloatKeyframeContainer; 
     101     
     102    typedef TemplateKeyframe<double> DoubleKeyframe; 
     103    typedef TemplateKeyframeContainer<double> DoubleKeyframeContainer;     
    101104 
    102105    typedef TemplateKeyframe<osg::Vec2> Vec2Keyframe; 
     
    117120    typedef TemplateKeyframe<FloatCubicBezier> FloatCubicBezierKeyframe; 
    118121    typedef TemplateKeyframeContainer<FloatCubicBezier> FloatCubicBezierKeyframeContainer; 
     122     
    119123    typedef TemplateKeyframe<DoubleCubicBezier> DoubleCubicBezierKeyframe; 
    120124    typedef TemplateKeyframeContainer<DoubleCubicBezier> DoubleCubicBezierKeyframeContainer; 
     125     
    121126    typedef TemplateKeyframe<Vec2CubicBezier> Vec2CubicBezierKeyframe; 
    122127    typedef TemplateKeyframeContainer<Vec2CubicBezier> Vec2CubicBezierKeyframeContainer; 
     128     
    123129    typedef TemplateKeyframe<Vec3CubicBezier> Vec3CubicBezierKeyframe; 
    124130    typedef TemplateKeyframeContainer<Vec3CubicBezier> Vec3CubicBezierKeyframeContainer; 
     131     
    125132    typedef TemplateKeyframe<Vec4CubicBezier> Vec4CubicBezierKeyframe; 
    126133    typedef TemplateKeyframeContainer<Vec4CubicBezier> Vec4CubicBezierKeyframeContainer; 
  • OpenSceneGraph/trunk/include/osgAnimation/LinkVisitor

    r9377 r9877  
    3333        META_NodeVisitor("osgAnimation","LinkVisitor") 
    3434 
    35         void apply(osg::Node& node)  
     35        void apply(osg::Node& node) 
    3636        { 
    3737            osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(node.getUpdateCallback()); 
  • OpenSceneGraph/trunk/include/osgAnimation/Skeleton

    r9373 r9877  
    3939        Skeleton(); 
    4040        void setDefaultUpdateCallback(void); 
    41         void computeBindMatrix() { _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); } 
     41        void computeBindMatrix() { _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); _needToRecomputeBindMatrix = false; } 
    4242    }; 
    4343 
  • OpenSceneGraph/trunk/src/osgAnimation/AnimationManagerBase.cpp

    r9456 r9877  
    3838void AnimationManagerBase::operator()(osg::Node* node, osg::NodeVisitor* nv) 
    3939{  
    40     if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)  
     40    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) 
    4141    { 
    4242        if (needToLink()) 
  • OpenSceneGraph/trunk/src/osgAnimation/BasicAnimationManager.cpp

    r9673 r9877  
    4848{ 
    4949    if (!findAnimation(pAnimation)) 
    50     { 
    5150        return; 
    52     } 
    5351 
    5452    if ( isPlaying(pAnimation) ) 
     
    5654   
    5755    _animationsPlaying[priority].push_back(pAnimation); 
     56    // for debug 
     57    //std::cout << "player Animation " << pAnimation->getName() << " at " << _lastUpdate << std::endl; 
    5858    pAnimation->setStartTime(_lastUpdate); 
    5959    pAnimation->setWeight(weight); 
     
    6363{ 
    6464    // search though the layer and remove animation 
    65     for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )  
     65    for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim ) 
    6666    { 
    6767        AnimationList& list = iterAnim->second; 
     
    8080void BasicAnimationManager::update (double time) 
    8181{ 
    82     if (!_lastUpdate) 
    83         _lastUpdate = time; 
     82    _lastUpdate = time; // keep time of last update 
    8483 
    8584    // could filtered with an active flag 
     
    9594        for (unsigned int i = 0; i < list.size(); i++) 
    9695        { 
    97             if (! list[i]->update(time)) 
     96            if (! list[i]->update(time))  
     97            { 
     98                // debug 
     99                // std::cout << list[i]->getName() << " finished at " << time << std::endl; 
    98100                toremove.push_back(i); 
     101            } else  
     102            { 
     103                // debug 
     104                //std::cout << list[i]->getName() << " updated" << std::endl; 
     105            } 
    99106        } 
    100107 
  • OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp

    r9370 r9877  
    1717#include <osgAnimation/Skeleton> 
    1818 
    19 osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop): 
     19osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) : 
    2020    osgAnimation::AnimationUpdateCallback(apc, copyop), 
    2121    _position(apc._position), 
     
    2626 
    2727 
    28 osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) 
    29     : osg::Transform(b,copyop), 
    30       _position(b._position), 
     28osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) : 
     29    osg::Transform(b,copyop), 
     30    _position(b._position), 
    3131    _rotation(b._rotation), 
    32     _scale(b._scale)  
     32    _scale(b._scale), 
     33    _needToRecomputeBindMatrix(true) 
    3334{ 
    3435} 
     
    5758    if (!parent) 
    5859    { 
    59 #if 0 
    60         // no more parent means, we get the skeleton 
    61         if (getParents().empty()) { 
    62             osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl; 
    63             return; 
    64         } else if (getParents().size() > 1) { 
    65             osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you have more than one parent in a skeleton structure (" << getName() <<") unknown behaviour" << std::endl; 
    66             return; 
    67         } 
    68         osgAnimation::Skeleton* skel = dynamic_cast<osgAnimation::Skeleton*>(getParents()[0]); 
    69         if (!skel) { 
    70             osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl; 
    71             return; 
    72         } 
    73         _invBindInSkeletonSpace = osg::Matrix::inverse(skel->getMatrix()) * _invBindInSkeletonSpace; 
    74 #else 
    7560        osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl; 
    76 #endif 
    7761        return; 
    7862    } 
  • OpenSceneGraph/trunk/src/osgAnimation/CMakeLists.txt

    r9673 r9877  
    1111SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME}) 
    1212SET(LIB_PUBLIC_HEADERS 
     13    ${HEADER_PATH}/Animation 
     14    ${HEADER_PATH}/AnimationManagerBase 
     15    ${HEADER_PATH}/Assert 
     16    ${HEADER_PATH}/BasicAnimationManager 
     17    ${HEADER_PATH}/Bone 
     18    ${HEADER_PATH}/Channel 
     19    ${HEADER_PATH}/CubicBezier 
     20    ${HEADER_PATH}/EaseMotion 
    1321    ${HEADER_PATH}/Export 
    14     ${HEADER_PATH}/Bone 
     22    ${HEADER_PATH}/Interpolator 
     23    ${HEADER_PATH}/Keyframe 
     24    ${HEADER_PATH}/LinkVisitor 
     25    ${HEADER_PATH}/MorphGeometry 
     26    ${HEADER_PATH}/RigGeometry 
     27    ${HEADER_PATH}/Sampler 
    1528    ${HEADER_PATH}/Skeleton 
    16     ${HEADER_PATH}/Channel 
    17     ${HEADER_PATH}/Sampler 
    18     ${HEADER_PATH}/Interpolator 
     29    ${HEADER_PATH}/Skinning 
    1930    ${HEADER_PATH}/Target 
    20     ${HEADER_PATH}/Animation 
    21     ${HEADER_PATH}/Keyframe 
    22     ${HEADER_PATH}/Skinning 
    23     ${HEADER_PATH}/CubicBezier 
     31    ${HEADER_PATH}/Timeline 
     32    ${HEADER_PATH}/TimelineAnimationManager 
     33    ${HEADER_PATH}/UpdateCallback 
    2434    ${HEADER_PATH}/Vec3Packed 
    25     ${HEADER_PATH}/BasicAnimationManager 
    26     ${HEADER_PATH}/TimelineAnimationManager 
    27     ${HEADER_PATH}/AnimationManagerBase 
    28     ${HEADER_PATH}/UpdateCallback 
    29     ${HEADER_PATH}/LinkVisitor 
    3035    ${HEADER_PATH}/VertexInfluence 
    31     ${HEADER_PATH}/EaseMotion 
    32     ${HEADER_PATH}/Assert 
    33     ${HEADER_PATH}/Timeline 
    34     ${HEADER_PATH}/RigGeometry 
    3536) 
    3637 
     
    3940    ${OPENSCENEGRAPH_USER_DEFINED_DYNAMIC_OR_STATIC} 
    4041    ${LIB_PUBLIC_HEADERS} 
    41     Channel.cpp 
    42     Target.cpp 
    4342    Animation.cpp 
    44     Bone.cpp 
    45     RigGeometry.cpp 
     43    AnimationManagerBase.cpp 
    4644    AnimationManager.cpp 
    4745    BasicAnimationManager.cpp 
     46    Bone.cpp 
     47    Channel.cpp 
     48    MorphGeometry.cpp 
     49    RigGeometry.cpp 
     50    Skeleton.cpp 
     51    Target.cpp 
    4852    TimelineAnimationManager.cpp 
    49     AnimationManagerBase.cpp 
    50     Skeleton.cpp 
     53    Timeline.cpp 
     54    UpdateCallback.cpp 
    5155    VertexInfluence.cpp 
    52     UpdateCallback.cpp 
    53     Timeline.cpp 
    5456    ${OPENSCENEGRAPH_VERSIONINFO_RC} 
    5557) 
  • OpenSceneGraph/trunk/src/osgAnimation/Skeleton.cpp

    r9531 r9877  
    2828        if (!bone) 
    2929            return; 
    30         bone->computeBindMatrix(); 
     30        if (bone->needToComputeBindMatrix()) 
     31            bone->computeBindMatrix(); 
     32 
    3133        traverse(node); 
    3234    } 
  • OpenSceneGraph/trunk/src/osgPlugins/osgAnimation/ReaderWriter.cpp

    r9620 r9877  
    2727#include <osgAnimation/Skeleton> 
    2828#include <osgAnimation/RigGeometry> 
     29#include <osgAnimation/MorphGeometry> 
    2930#include <osgAnimation/UpdateCallback> 
    3031 
     
    122123    ); 
    123124 
    124  
    125  
    126  
    127 bool Animation_readLocalData(Object& obj, Input& fr)  
     125// Helper method for reading channels 
     126bool Animation_readChannel(osgAnimation::Channel* pChannel, Input& fr) 
     127{ 
     128    bool iteratorAdvanced = false; 
     129    std::string name = "unknown"; 
     130    if (fr.matchSequence("name %s"))  
     131    { 
     132        if (fr[1].getStr()) 
     133            name = fr[1].getStr(); 
     134        fr += 2; 
     135        iteratorAdvanced = true; 
     136    } 
     137    pChannel->setName(name); 
     138 
     139    std::string target = "unknown"; 
     140    if (fr.matchSequence("target %s"))  
     141    { 
     142        if (fr[1].getStr()) 
     143            target = fr[1].getStr(); 
     144        fr += 2; 
     145        iteratorAdvanced = true; 
     146    } 
     147    pChannel->setTargetName(target); 
     148 
     149    float weight = 1.0; 
     150    if (fr.matchSequence("weight %f"))  
     151    { 
     152        fr[1].getFloat(weight); 
     153        fr += 2; 
     154        iteratorAdvanced = true; 
     155    } 
     156    pChannel->setWeight(weight); 
     157    return iteratorAdvanced; 
     158} 
     159 
     160bool Animation_readLocalData(Object& obj, Input& fr) 
    128161{ 
    129162    osgAnimation::Animation& anim = dynamic_cast<osgAnimation::Animation&>(obj); 
    130163    bool iteratorAdvanced = false; 
     164 
     165    if (fr.matchSequence("playmode %w")) 
     166    { 
     167        if      (fr[1].matchWord("ONCE")) anim.setPlaymode(osgAnimation::Animation::ONCE); 
     168        else if (fr[1].matchWord("STAY")) anim.setPlaymode(osgAnimation::Animation::STAY); 
     169        else if (fr[1].matchWord("LOOP")) anim.setPlaymode(osgAnimation::Animation::LOOP); 
     170        else if (fr[1].matchWord("PPONG")) anim.setPlaymode(osgAnimation::Animation::PPONG); 
     171        fr += 2; 
     172        iteratorAdvanced = true; 
     173    } 
     174 
     175    if (fr.matchSequence("weight %f"))  
     176    { 
     177        float weight; 
     178        fr[1].getFloat(weight); 
     179        fr += 2; 
     180        iteratorAdvanced = true; 
     181        anim.setWeight(weight); 
     182    } 
     183     
     184    if (fr.matchSequence("duration %f"))  
     185    { 
     186        float duration; 
     187        fr[1].getFloat(duration); 
     188        fr += 2; 
     189        iteratorAdvanced = true; 
     190        anim.setDuration(duration); 
     191    } 
     192 
     193    if (fr.matchSequence("starttime %f"))  
     194    { 
     195        float starttime; 
     196        fr[1].getFloat(starttime); 
     197        fr += 2; 
     198        iteratorAdvanced = true; 
     199        anim.setStartTime(starttime); 
     200    } 
     201 
    131202    int nbChannels = 0; 
    132203    if (fr.matchSequence("num_channels %i"))  
     
    139210    for (int i = 0; i < nbChannels; i++)  
    140211    { 
    141         if (fr.matchSequence("Channel {"))  
     212        if (fr.matchSequence("DoubleLinearChannel {"))  
     213        { 
     214            fr += 2; 
     215 
     216            osgAnimation::DoubleLinearChannel* channel = new osgAnimation::DoubleLinearChannel; 
     217 
     218            if (Animation_readChannel(channel, fr)) 
     219                iteratorAdvanced = true; 
     220                  
     221            int nbKeys; 
     222            if (fr.matchSequence("Keyframes %i {"))  
     223            { 
     224                fr[1].getInt(nbKeys); 
     225                fr += 3; 
     226                iteratorAdvanced = true; 
     227 
     228                for (int k = 0; k < nbKeys; k++)  
     229                { 
     230                    double v; 
     231                    float time; 
     232                    if (fr.matchSequence("key %f %f")) 
     233                    { 
     234                        fr[1].getFloat(time); 
     235                        fr[2].getFloat(v); 
     236                        fr += 3; 
     237                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::DoubleKeyframe(time, v)); 
     238                        iteratorAdvanced = true; 
     239                    } 
     240                } 
     241                anim.addChannel(channel); 
     242 
     243                if (fr.matchSequence("}")) // keyframes 
     244                    fr += 1; 
     245            } 
     246            if (fr.matchSequence("}")) // channel 
     247                fr += 1; 
     248        } 
     249        else if (fr.matchSequence("FloatLinearChannel {"))  
     250        { 
     251            fr += 2; 
     252 
     253            osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel; 
     254 
     255            if (Animation_readChannel(channel, fr)) 
     256                iteratorAdvanced = true; 
     257                  
     258            int nbKeys; 
     259            if (fr.matchSequence("Keyframes %i {"))  
     260            { 
     261                fr[1].getInt(nbKeys); 
     262                fr += 3; 
     263                iteratorAdvanced = true; 
     264 
     265                for (int k = 0; k < nbKeys; k++)  
     266                { 
     267                    float v; 
     268                    float time; 
     269                    if (fr.matchSequence("key %f %f")) 
     270                    { 
     271                        fr[1].getFloat(time); 
     272                        fr[2].getFloat(v); 
     273                        fr += 3; 
     274                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(time, v)); 
     275                        iteratorAdvanced = true; 
     276                    } 
     277                } 
     278                anim.addChannel(channel); 
     279 
     280                if (fr.matchSequence("}")) // keyframes 
     281                    fr += 1; 
     282            } 
     283            if (fr.matchSequence("}")) // channel 
     284                fr += 1; 
     285        } 
     286        else if (fr.matchSequence("Vec2LinearChannel {"))  
     287        { 
     288            fr += 2; 
     289 
     290            osgAnimation::Vec2LinearChannel* channel = new osgAnimation::Vec2LinearChannel; 
     291 
     292            if (Animation_readChannel(channel, fr)) 
     293                iteratorAdvanced = true; 
     294                  
     295            int nbKeys; 
     296            if (fr.matchSequence("Keyframes %i {"))  
     297            { 
     298                fr[1].getInt(nbKeys); 
     299                fr += 3; 
     300                iteratorAdvanced = true; 
     301 
     302                for (int k = 0; k < nbKeys; k++)  
     303                { 
     304                    osg::Vec2 v; 
     305                    float time; 
     306                    if (fr.matchSequence("key %f %f %f")) 
     307                    { 
     308                        fr[1].getFloat(time); 
     309                        fr[2].getFloat(v[0]); 
     310                        fr[3].getFloat(v[1]); 
     311                        fr += 4; 
     312                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec2Keyframe(time, v)); 
     313                        iteratorAdvanced = true; 
     314                    } 
     315                } 
     316                anim.addChannel(channel); 
     317 
     318                if (fr.matchSequence("}")) // keyframes 
     319                    fr += 1; 
     320            } 
     321            if (fr.matchSequence("}")) // channel 
     322                fr += 1; 
     323        } 
     324        else if (fr.matchSequence("Vec3LinearChannel {"))  
     325        { 
     326            fr += 2; 
     327 
     328            osgAnimation::Vec3LinearChannel* channel = new osgAnimation::Vec3LinearChannel; 
     329 
     330            if (Animation_readChannel(channel, fr)) 
     331                iteratorAdvanced = true; 
     332                  
     333            int nbKeys; 
     334            if (fr.matchSequence("Keyframes %i {"))  
     335            { 
     336                fr[1].getInt(nbKeys); 
     337                fr += 3; 
     338                iteratorAdvanced = true; 
     339 
     340                for (int k = 0; k < nbKeys; k++)  
     341                { 
     342                    osg::Vec3 v; 
     343                    float time; 
     344                    if (fr.matchSequence("key %f %f %f %f")) 
     345                    { 
     346                        fr[1].getFloat(time); 
     347                        fr[2].getFloat(v[0]); 
     348                        fr[3].getFloat(v[1]); 
     349                        fr[4].getFloat(v[2]); 
     350                        fr += 5; 
     351                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(time, v)); 
     352                        iteratorAdvanced = true; 
     353                    } 
     354                } 
     355                anim.addChannel(channel); 
     356 
     357                if (fr.matchSequence("}")) // keyframes 
     358                    fr += 1; 
     359            } 
     360            if (fr.matchSequence("}")) // channel 
     361                fr += 1; 
     362        } 
     363        else if (fr.matchSequence("Vec4LinearChannel {"))  
     364        { 
     365            fr += 2; 
     366 
     367            osgAnimation::Vec4LinearChannel* channel = new osgAnimation::Vec4LinearChannel; 
     368 
     369            if (Animation_readChannel(channel, fr)) 
     370                iteratorAdvanced = true; 
     371                  
     372            int nbKeys; 
     373            if (fr.matchSequence("Keyframes %i {"))  
     374            { 
     375                fr[1].getInt(nbKeys); 
     376                fr += 3; 
     377                iteratorAdvanced = true; 
     378 
     379                for (int k = 0; k < nbKeys; k++)  
     380                { 
     381                    osg::Vec4 v; 
     382                    float time; 
     383                    if (fr.matchSequence("key %f %f %f %f %f")) 
     384                    { 
     385                        fr[1].getFloat(time); 
     386                        fr[2].getFloat(v[0]); 
     387                        fr[3].getFloat(v[1]); 
     388                        fr[4].getFloat(v[2]); 
     389                        fr[5].getFloat(v[3]); 
     390                        fr += 6; 
     391                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec4Keyframe(time, v)); 
     392                        iteratorAdvanced = true; 
     393                    } 
     394                } 
     395                anim.addChannel(channel); 
     396 
     397                if (fr.matchSequence("}")) // keyframes 
     398                    fr += 1; 
     399            } 
     400            if (fr.matchSequence("}")) // channel 
     401                fr += 1; 
     402        } 
     403        else if (fr.matchSequence("QuatSphericalLinearChannel {"))  
     404        { 
     405            fr += 2; 
     406 
     407            osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel; 
     408 
     409            if (Animation_readChannel(channel, fr)) 
     410                iteratorAdvanced = true; 
     411                  
     412            int nbKeys; 
     413            if (fr.matchSequence("Keyframes %i {"))  
     414            { 
     415                fr[1].getInt(nbKeys); 
     416                fr += 3; 
     417                iteratorAdvanced = true; 
     418 
     419                for (int k = 0; k < nbKeys; k++)  
     420                { 
     421                    osg::Quat q; 
     422                    float time; 
     423                    if (fr.matchSequence("key %f %f %f %f %f")) 
     424                    { 
     425                        fr[1].getFloat(time); 
     426                        fr[2].getFloat(q[0]); 
     427                        fr[3].getFloat(q[1]); 
     428                        fr[4].getFloat(q[2]); 
     429                        fr[5].getFloat(q[3]); 
     430                        fr += 6; 
     431                        channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::QuatKeyframe(time, q)); 
     432                        iteratorAdvanced = true; 
     433                    } 
     434                } 
     435                anim.addChannel(channel); 
     436 
     437                if (fr.matchSequence("}")) // keyframes 
     438                    fr += 1; 
     439            } 
     440            if (fr.matchSequence("}")) // channel 
     441                fr += 1; 
     442        } 
     443        // Deprecated 
     444        // Reading of old channel info  
     445        // Kept here for easy conversion of old .osg data to new format 
     446        else if (fr.matchSequence("Channel {"))  
    142447        { 
    143448            fr += 2; 
     
    146451            if (fr.matchSequence("name %s"))  
    147452            { 
    148                 name = fr[1].getStr(); 
     453                if (fr[1].getStr()) 
     454                    name = fr[1].getStr(); 
    149455                fr += 2; 
    150456                iteratorAdvanced = true; 
     
    153459            if (fr.matchSequence("target %s"))  
    154460            { 
    155                 target = fr[1].getStr(); 
     461                if (fr[1].getStr()) 
     462                    target = fr[1].getStr(); 
    156463                fr += 2; 
    157464                iteratorAdvanced = true; 
    158465            } 
    159466 
    160             std::string type; 
     467            std::string type = "unknown"; 
    161468            int nbKeys; 
    162469            if (fr.matchSequence("Keyframes %s %i {"))  
    163470            { 
    164                 type = fr[1].getStr(); 
     471                if (fr[1].getStr()) 
     472                    type = fr[1].getStr(); 
    165473                fr[2].getInt(nbKeys); 
    166474                fr += 4; 
     
    176484                else if (type == "Vec3")  
    177485                { 
    178                     channel = new osgAnimation::Vec3LinearChannel; 
    179486                    osgAnimation::Vec3LinearChannel* c = new osgAnimation::Vec3LinearChannel; 
    180487                    c->getOrCreateSampler()->getOrCreateKeyframeContainer(); 
    181488                    channel = c; 
    182489                } 
     490 
    183491                if (channel)  
    184492                { 
     
    230538} 
    231539 
    232 bool Animation_writeLocalData(const Object& obj, Output& fw) 
    233 { 
    234     const osgAnimation::Animation& anim = dynamic_cast<const osgAnimation::Animation&>(obj); 
    235  
    236     fw.indent() << "num_channels " << anim.getChannels().size()  << std::endl; 
    237     for (unsigned int i = 0; i < anim.getChannels().size(); i++)  
    238     { 
    239         fw.indent() << "Channel {" << std::endl; 
     540// Helper method for writing channels 
     541template <typename ChannelType, typename ContainerType> 
     542void Animation_writeChannel(const std::string& channelString, ChannelType* pChannel, Output& fw) 
     543{ 
     544    fw.indent() << channelString.c_str() << " {" << std::endl; 
     545    fw.moveIn(); 
     546    fw.indent() << "name \"" << pChannel->getName() << "\"" << std::endl; 
     547    fw.indent() << "target \"" << pChannel->getTargetName() << "\"" << std::endl; 
     548 
     549    fw.indent() << "weight " << pChannel->getWeight() << std::endl; 
     550 
     551    ContainerType* kfc  = pChannel->getSamplerTyped()->getKeyframeContainerTyped(); 
     552    if (kfc) 
     553    { 
     554        fw.indent() << "Keyframes " << kfc->size() << " {" << std::endl; 
    240555        fw.moveIn(); 
    241         fw.indent() << "name \"" << anim.getChannels()[i]->getName() << "\"" << std::endl; 
    242         fw.indent() << "target \"" << anim.getChannels()[i]->getTargetName() << "\"" << std::endl; 
    243  
    244         std::string type = "unknown"; 
    245         if (anim.getChannels()[i]->getName() == std::string("quaternion"))  
    246         { 
    247             type = "Quat"; 
    248         } 
    249         else if (anim.getChannels()[i]->getName() == std::string("rotation"))  
    250         { 
    251             type = "Quat"; 
    252         } 
    253         else if (anim.getChannels()[i]->getName() == std::string("euler"))  
    254         { 
    255             type = "Vec3"; 
    256         } 
    257         else if (anim.getChannels()[i]->getName() == std::string("scale"))  
    258         { 
    259             type = "Vec3"; 
    260         } 
    261         else if (anim.getChannels()[i]->getName() == std::string("position"))  
    262         { 
    263             type = "Vec3"; 
    264         } 
    265  
    266         osgAnimation::KeyframeContainer* kf = anim.getChannels()[i]->getSampler()->getKeyframeContainer(); 
    267         fw.indent() << "Keyframes \"" << type << "\" " << kf->size() << " {" << std::endl; 
    268         fw.moveIn(); 
    269         for (unsigned int k = 0; k < kf->size(); k++)  
    270         { 
    271             if (type == "Vec3")  
    272             { 
    273                 osgAnimation::Vec3KeyframeContainer* kk = dynamic_cast<osgAnimation::Vec3KeyframeContainer*>(kf); 
    274                 fw.indent() << "key " << (*kk)[k].getTime() << " " <<  (*kk)[k].getValue() << std::endl; 
    275             } 
    276             else if ( type == "Quat")  
    277             { 
    278                 osgAnimation::QuatKeyframeContainer* kk = dynamic_cast<osgAnimation::QuatKeyframeContainer*>(kf); 
    279                 fw.indent() << "key " << (*kk)[k].getTime() << " " <<  (*kk)[k].getValue() << std::endl; 
    280             } 
     556        for (unsigned int k = 0; k < kfc->size(); k++)  
     557        { 
     558            fw.indent() << "key " << (*kfc)[k].getTime() << " " <<  (*kfc)[k].getValue() << std::endl; 
    281559        } 
    282560        fw.moveOut(); 
     
    284562        fw.moveOut(); 
    285563        fw.indent() << "}" << std::endl; 
     564    } 
     565} 
     566 
     567bool Animation_writeLocalData(const Object& obj, Output& fw) 
     568{ 
     569    const osgAnimation::Animation& anim = dynamic_cast<const osgAnimation::Animation&>(obj); 
     570 
     571    switch (anim.getPlayMode())  
     572    { 
     573    case osgAnimation::Animation::ONCE: 
     574        fw.indent() << "playmode ONCE" << std::endl; 
     575        break; 
     576    case osgAnimation::Animation::STAY: 
     577        fw.indent() << "playmode STAY" << std::endl; 
     578        break; 
     579    case osgAnimation::Animation::LOOP: 
     580        fw.indent() << "playmode LOOP" << std::endl; 
     581        break; 
     582    case osgAnimation::Animation::PPONG:  
     583        fw.indent() << "playmode PPONG" << std::endl; 
     584        break; 
     585    default: 
     586        break; 
     587    } 
     588 
     589    fw.indent() << "weight " << anim.getWeight() << std::endl; 
     590    fw.indent() << "duration " << anim.getDuration() << std::endl; 
     591    fw.indent() << "starttime " << anim.getStartTime() << std::endl; 
     592 
     593    fw.indent() << "num_channels " << anim.getChannels().size()  << std::endl; 
     594    for (unsigned int i = 0; i < anim.getChannels().size(); i++)  
     595    { 
     596        osgAnimation::Channel* pChannel = anim.getChannels()[i]; 
     597 
     598        osgAnimation::DoubleLinearChannel* pDlc = dynamic_cast<osgAnimation::DoubleLinearChannel*>(pChannel); 
     599        if (pDlc) 
     600        { 
     601            Animation_writeChannel<osgAnimation::DoubleLinearChannel, osgAnimation::DoubleKeyframeContainer>("DoubleLinearChannel",  pDlc, fw); 
     602            continue; 
     603        } 
     604        osgAnimation::FloatLinearChannel* pFlc = dynamic_cast<osgAnimation::FloatLinearChannel*>(pChannel); 
     605        if (pFlc) 
     606        { 
     607            Animation_writeChannel<osgAnimation::FloatLinearChannel, osgAnimation::FloatKeyframeContainer>("FloatLinearChannel",  pFlc, fw); 
     608            continue; 
     609        } 
     610        osgAnimation::Vec2LinearChannel* pV2lc = dynamic_cast<osgAnimation::Vec2LinearChannel*>(pChannel); 
     611        if (pV2lc) 
     612        { 
     613            Animation_writeChannel<osgAnimation::Vec2LinearChannel, osgAnimation::Vec2KeyframeContainer>("Vec2LinearChannel",  pV2lc, fw); 
     614            continue; 
     615        } 
     616        osgAnimation::Vec3LinearChannel* pV3lc = dynamic_cast<osgAnimation::Vec3LinearChannel*>(pChannel); 
     617        if (pV3lc) 
     618        { 
     619            Animation_writeChannel<osgAnimation::Vec3LinearChannel, osgAnimation::Vec3KeyframeContainer>("Vec3LinearChannel",  pV3lc, fw); 
     620            continue; 
     621        } 
     622        osgAnimation::Vec4LinearChannel* pV4lc = dynamic_cast<osgAnimation::Vec4LinearChannel*>(pChannel); 
     623        if (pV4lc) 
     624        { 
     625            Animation_writeChannel<osgAnimation::Vec4LinearChannel, osgAnimation::Vec4KeyframeContainer>("Vec4LinearChannel",  pV4lc, fw); 
     626            continue; 
     627        } 
     628        osgAnimation::QuatSphericalLinearChannel* pQslc = dynamic_cast<osgAnimation::QuatSphericalLinearChannel*>(pChannel); 
     629        if (pQslc) 
     630        { 
     631            Animation_writeChannel<osgAnimation::QuatSphericalLinearChannel, osgAnimation::QuatKeyframeContainer>("QuatSphericalLinearChannel",  pQslc, fw); 
     632            continue; 
     633        } 
     634        osgAnimation::FloatCubicBezierChannel* pFcbc = dynamic_cast<osgAnimation::FloatCubicBezierChannel*>(pChannel); 
     635        if (pFcbc) 
     636        { 
     637            Animation_writeChannel<osgAnimation::FloatCubicBezierChannel, osgAnimation::FloatCubicBezierKeyframeContainer>("FloatCubicBezierChannel",  pFcbc, fw); 
     638            continue; 
     639        } 
     640        osgAnimation::DoubleCubicBezierChannel* pDcbc = dynamic_cast<osgAnimation::DoubleCubicBezierChannel*>(pChannel); 
     641        if (pDcbc) 
     642        { 
     643            Animation_writeChannel<osgAnimation::DoubleCubicBezierChannel, osgAnimation::DoubleCubicBezierKeyframeContainer>("DoubleCubicBezierChannel",  pDcbc, fw); 
     644            continue; 
     645        } 
     646        osgAnimation::Vec2CubicBezierChannel* pV2cbc = dynamic_cast<osgAnimation::Vec2CubicBezierChannel*>(pChannel); 
     647        if (pV2cbc) 
     648        { 
     649            Animation_writeChannel<osgAnimation::Vec2CubicBezierChannel, osgAnimation::Vec2CubicBezierKeyframeContainer>("Vec2CubicBezierChannel",  pV2cbc, fw); 
     650            continue; 
     651        } 
     652        osgAnimation::Vec3CubicBezierChannel* pV3cbc = dynamic_cast<osgAnimation::Vec3CubicBezierChannel*>(pChannel); 
     653        if (pV3cbc) 
     654        { 
     655            Animation_writeChannel<osgAnimation::Vec3CubicBezierChannel, osgAnimation::Vec3CubicBezierKeyframeContainer>("Vec3CubicBezierChannel",  pV3cbc, fw); 
     656            continue; 
     657        } 
     658        osgAnimation::Vec4CubicBezierChannel* pV4cbc = dynamic_cast<osgAnimation::Vec4CubicBezierChannel*>(pChannel); 
     659        if (pV4cbc) 
     660        { 
     661            Animation_writeChannel<osgAnimation::Vec4CubicBezierChannel, osgAnimation::Vec4CubicBezierKeyframeContainer>("Vec4CubicBezierChannel",  pV4cbc, fw); 
     662            continue; 
     663        } 
    286664    } 
    287665    return true; 
     
    479857 
    480858 
     859bool MorphGeometry_readLocalData(Object& obj, Input& fr)  
     860{ 
     861    osgAnimation::MorphGeometry& geom = dynamic_cast<osgAnimation::MorphGeometry&>(obj); 
     862 
     863    bool iteratorAdvanced = false; 
     864 
     865    if (fr[0].matchWord("method")) 
     866    { 
     867        if (fr[1].matchWord("NORMALIZED")) 
     868        { 
     869            geom.setMethod(osgAnimation::MorphGeometry::NORMALIZED); 
     870            fr+=2; 
     871            iteratorAdvanced = true; 
     872        } 
     873        else if  (fr[1].matchWord("RELATIVE")) 
     874        { 
     875            geom.setMethod(osgAnimation::MorphGeometry::RELATIVE); 
     876            fr+=2; 
     877            iteratorAdvanced = true; 
     878        } 
     879    } 
     880 
     881    if (fr[0].matchWord("morphNormals")) 
     882    { 
     883        if (fr[1].matchWord("TRUE")) 
     884        { 
     885            geom.setMorphNormals(true); 
     886            fr+=2; 
     887            iteratorAdvanced = true; 
     888        } 
     889        else if (fr[1].matchWord("FALSE")) 
     890        { 
     891            geom.setMorphNormals(false); 
     892            fr+=2; 
     893            iteratorAdvanced = true; 
     894        } 
     895    } 
     896 
     897    int num_morphTargets = 0; 
     898    if (fr.matchSequence("num_morphTargets %i")) 
     899    { 
     900        fr[1].getInt(num_morphTargets); 
     901        fr += 2; 
     902        iteratorAdvanced = true; 
     903    } 
     904 
     905    for (int i = 0; i < num_morphTargets; i++) 
     906    { 
     907        if (fr.matchSequence("MorphTarget {")) 
     908        { 
     909            int entry = fr[0].getNoNestedBrackets(); 
     910            fr += 2; 
     911            iteratorAdvanced = true; 
     912 
     913            while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) 
     914            { 
     915 
     916                float weight = 1.0; 
     917                if (fr.matchSequence("weight %f"))  
     918                { 
     919                    fr[1].getFloat(weight); 
     920                    fr += 2; 
     921                } 
     922                osg::Drawable* drawable = NULL; 
     923                drawable = fr.readDrawable(); 
     924                osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(drawable); 
     925                if (geometry) 
     926                    geom.addMorphTarget(geometry, weight); 
     927            } 
     928            if (fr.matchSequence("}")) 
     929                fr += 1; 
     930        } 
     931    } 
     932 
     933    return iteratorAdvanced; 
     934} 
     935 
     936bool MorphGeometry_writeLocalData(const Object& obj, Output& fw)  
     937{ 
     938    const osgAnimation::MorphGeometry& geom = dynamic_cast<const osgAnimation::MorphGeometry&>(obj); 
     939 
     940    switch(geom.getMethod()) 
     941    { 
     942        case(osgAnimation::MorphGeometry::NORMALIZED): fw.indent() << "method NORMALIZED"<<std::endl; break; 
     943    case(osgAnimation::MorphGeometry::RELATIVE): fw.indent() << "method RELATIVE"<<std::endl; break; 
     944    } 
     945 
     946    fw.indent() << "morphNormals "; 
     947    if (geom.getMorphNormals())  
     948        fw << "TRUE" << std::endl; 
     949    else  
     950        fw << "FALSE" << std::endl; 
     951 
     952    const osgAnimation::MorphGeometry::MorphTargetList& morphTargets = geom.getMorphTargetList(); 
     953    fw.indent() << "num_morphTargets " << morphTargets.size() << std::endl; 
     954    for (unsigned int i = 0; i < morphTargets.size(); i++) 
     955    { 
     956        fw.indent() << "MorphTarget {" << std::endl; 
     957        fw.moveIn(); 
     958        fw.indent() << "weight " << morphTargets[i].getWeight() <<std::endl; 
     959        fw.writeObject(*morphTargets[i].getGeometry()); 
     960        fw.moveOut(); 
     961        fw.indent() << "}" << std::endl; 
     962    } 
     963    return true; 
     964} 
     965 
     966RegisterDotOsgWrapperProxy g_osgAnimationMorphGeometryProxy 
     967( 
     968    new osgAnimation::MorphGeometry, 
     969    "osgAnimation::MorphGeometry", 
     970    "Object Drawable osgAnimation::MorphGeometry Geometry", 
     971    &MorphGeometry_readLocalData, 
     972    &MorphGeometry_writeLocalData, 
     973    DotOsgWrapper::READ_AND_WRITE 
     974    ); 
     975 
    481976 
    482977bool UpdateBone_readLocalData(Object& obj, Input& fr)  
     
    5471042); 
    5481043 
     1044bool UpdateMorph_readLocalData(Object& obj, Input& fr)  
     1045{ 
     1046    bool iteratorAdvanced = false; 
     1047    return iteratorAdvanced; 
     1048} 
     1049 
     1050bool UpdateMorph_writeLocalData(const Object& obj, Output& fw) 
     1051{ 
     1052    return true; 
     1053} 
     1054 
     1055RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy 
     1056( 
     1057 new osgAnimation::UpdateMorph, 
     1058    "osgAnimation::UpdateMorph", 
     1059    "Object NodeCallback osgAnimation::UpdateMorph", 
     1060    &UpdateMorph_readLocalData, 
     1061    &UpdateMorph_writeLocalData, 
     1062    DotOsgWrapper::READ_AND_WRITE 
     1063); 
     1064