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".

This commit is contained in:
Robert Osfield
2007-02-21 21:20:33 +00:00
parent 455b046433
commit 8dc84d0a8f

View File

@@ -151,15 +151,22 @@ class Group : public PrimaryRecord
static const unsigned int BACKWARD_ANIM = 0x80000000u >> 6;
osg::ref_ptr<osg::Group> _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<osg::Sequence> 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<osg::Sequence*>(_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<osg::Sequence*>(_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);
}
}
};