From 8dc84d0a8f2664d72ee9dfaeff81b0342253f5cd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 21 Feb 2007 21:20:33 +0000 Subject: [PATCH] From Brede Johansen, Thanks for the model it helped to understand the problem. In Creator the "Last Frame Duration" is performed on the last frame of the last loop iteration, I tried to use it for the last frame of every loop iteration. As you already have explained we need a custom Sequence node. In the osgSim nodekit we already have a couple of specialized nodes for the OpenFlight format. We need an osgSim::GroupAnimation but I don't have the time right now to take this challenge. Until then I have modified my last attempt to work with the current osg::Sequence node by ignoring the "Last Frame Duration". --- src/osgPlugins/OpenFlight/PrimaryRecords.cpp | 90 +++++++++++--------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp index 65691d4db..320972b94 100644 --- a/src/osgPlugins/OpenFlight/PrimaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/PrimaryRecords.cpp @@ -151,15 +151,22 @@ class Group : public PrimaryRecord static const unsigned int BACKWARD_ANIM = 0x80000000u >> 6; osg::ref_ptr _group; + uint32 _flags; bool _forwardAnim; bool _backwardAnim; + int32 _loopCount; float32 _loopDuration; + float32 _lastFrameDuration; public: Group(): + _flags(0), _forwardAnim(false), - _backwardAnim(false) + _backwardAnim(false), + _loopCount(0), + _loopDuration(0), + _lastFrameDuration(0) {} META_Record(Group) @@ -181,54 +188,33 @@ protected: /*int16 relativePriority =*/ in.readInt16(); in.forward(2); - uint32 flags = in.readUInt32(); + _flags = in.readUInt32(0); /*uint16 specialId0 =*/ in.readUInt16(); /*uint16 specialId1 =*/ in.readUInt16(); /*uint16 significance =*/ in.readUInt16(); /*int8 layer =*/ in.readInt8(); in.forward(5); // version >= VERSION_15_8 - /*uint32 loopCount =*/ in.readUInt32(); - _loopDuration = in.readFloat32(); - /*float32 lastFrameDuration =*/ in.readFloat32(); + _loopCount = in.readInt32(0); + _loopDuration = in.readFloat32(0.0f); + _lastFrameDuration = in.readFloat32(0.0f); // Check for forward animation (sequence) - _forwardAnim = (flags & FORWARD_ANIM) != 0; + _forwardAnim = (_flags & FORWARD_ANIM) != 0; // For versions prior to 15.8, the swing bit can be set independently // of the animation bit. This implies forward animation (with swing) - if ((document.version() < VERSION_15_8) && (flags & SWING_ANIM)) + if ((document.version() < VERSION_15_8) && (_flags & SWING_ANIM)) _forwardAnim = true; // OpenFlight 15.8 adds backwards animations _backwardAnim = ( (document.version() >= VERSION_15_8) && - ((flags & BACKWARD_ANIM) != 0) ); + ((_flags & BACKWARD_ANIM) != 0) ); if (_forwardAnim || _backwardAnim) - { - osg::ref_ptr sequence = new osg::Sequence; - - // Regardless of forwards or backwards, animation could have swing bit set - const osg::Sequence::LoopMode loopMode = ((flags & SWING_ANIM) == 0) ? - osg::Sequence::LOOP : osg::Sequence::SWING; - - if (_forwardAnim) - sequence->setInterval(loopMode, 0, -1); - else - sequence->setInterval(loopMode, -1, 0); - - // Set the duration, temporarily. We'll set the correct value - // in the destructor, when we know the number of children. - float speed=0.1f; - sequence->setDuration(speed); - sequence->setMode(osg::Sequence::START); - - _group = sequence.get(); - } + _group = new osg::Sequence; else - { _group = new osg::Group; - } _group->setName(id); @@ -239,17 +225,45 @@ protected: virtual void popLevel(Document& document) { - // Set loop duration? - if (document.version() >= VERSION_15_8) + // Children are added! + osg::Sequence* sequence = dynamic_cast(_group.get()); + if (sequence && sequence->getNumChildren() > 0) { - // Now that we know the number of children, set the loop duration - // to the best of our ability (currently, osg::Sequence doesn't - // support the OpenFlight last frame duration concept). - osg::Sequence* sequence = dynamic_cast(_group.get()); - if (sequence && sequence->getNumChildren()>0) + // Regardless of forwards or backwards, animation could have swing bit set. + osg::Sequence::LoopMode loopMode = ((_flags & SWING_ANIM) == 0) ? + osg::Sequence::LOOP : osg::Sequence::SWING; + + if (_forwardAnim) + sequence->setInterval(loopMode, 0, -1); + else + sequence->setInterval(loopMode, -1, 0); + + // Loop timing available from version 15.8. + if (document.version() >= VERSION_15_8) { - sequence->setDuration( _loopDuration / (float)(_group->getNumChildren()) ); + // Set frame duration. + float frameDuration = _loopDuration / float(sequence->getNumChildren()); + for (unsigned int i=0; i < sequence->getNumChildren(); i++) + sequence->setTime(i, frameDuration); + + // Set number of repetitions. + if (_loopCount > 0) + sequence->setDuration(1.0f, _loopCount); + else + sequence->setDuration(1.0f); // Run continuously } + else // No timing available. + { + // Set frame duration + float frameDuration = 0.1f; // 10Hz + for (unsigned int i=0; i < sequence->getNumChildren(); i++) + sequence->setTime(i, frameDuration); + + // Run continuously + sequence->setDuration(1.0f); + } + + sequence->setMode(osg::Sequence::START); } } };