createAnimationState not animating

Problems building or running the engine, queries about how to use features etc.
Post Reply
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

createAnimationState not animating

Post by TheComet »

I'm using the following code to create a new animation state from only a section of the model's animation, but the animation isn't playing. The model just stays static.

Code: Select all

m_AnimState = m_OgreEntity->getAllAnimationStates()->createAnimationState(
            "walk",
            0,
            40
    );
    m_AnimState->setLoop(true);
    m_AnimState->setEnabled(true);
Yes, the class is registered as a frameListener and yes, I am updating the animation.

Code: Select all

bool Entity::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    m_AnimState->addTime(evt.timeSinceLastFrame);
    return true;
}
If I list the animation states, I can confirm that "walk" was successfully added to the AnimationStateSet. I have no trouble playing the base animation "Anim_1", but "walk" won't play. What am I doing wrong?
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: createAnimationState not animating

Post by c6burns »

I thought createAnimationState creates a new blank animation state, and even throws an exception if you pass the name of an existing state.
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

Re: createAnimationState not animating

Post by TheComet »

According to the documentation it requires at least the name of the animation, the starting frame, and duration (which I've done), so there's really no way to create a blank state.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: createAnimationState not animating

Post by c6burns »

What I mean by blank is that there are no keyframes in it, so nothing happens when you enable it and add time.
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

Re: createAnimationState not animating

Post by TheComet »

c6burns wrote:What I mean by blank is that there are no keyframes in it, so nothing happens when you enable it and add time.
Ah. So how would I go about populating the new AnimationState with keyframes?
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: createAnimationState not animating

Post by c6burns »

For that I assume you would work directly with an animation as opposed to an animationstate (myEntity->getSkeleton()->getAnimation("my_anim_name")). Truth be told, I don't really know as I leave this up to my DCC tool exporter and I create all my animation tracks there.
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

Re: createAnimationState not animating

Post by TheComet »

Thanks for the quick answer! I feel I'm getting close.

I've tried two things, and both of them don't lead anywhere. My goal is to extract a small section of animation with length 40, starting at frame 20.

Attempt #1

Code: Select all

Ogre::Animation* walkAnim = m_OgreEntity->getSkeleton()->getAnimation("Anim_1")->clone("walk");
walkAnim->setLength(40);
walkAnim->setUseBaseKeyFrame(true, 20);
// PROBLEM: How do I apply this "walkAnim" to my skeleton now? There is no method "addAnimation()"
Attempt #2

Code: Select all

Ogre::Animation* walkAnim = m_OgreEntity->getSkeleton()->createAnimation("walk", 40);
// PROBLEM: How do I copy the existing animation "Anim_1" to my newly created animation?
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

Re: createAnimationState not animating

Post by TheComet »

Okay, either I'm stupid, or I'm just looking too deep.

What's the use of Animation having a clone() method? Skeleton has a removeAnimation() method, but no addAnimation(), so clone() is completely useless?
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: createAnimationState not animating

Post by c6burns »

I looked in my exporter (well not mine, but the one I use) and this is how it creates animations:
- Calling Skeleton::createAnimation
- Calling Animation::createNodeTrack for a specific bone
- Calling NodeAnimationTrack::createNodeKeyFrame for each keyframe it needs to create
- sets the rotation, translation and scale of the newly created keyframe
TheComet
Gnoblar
Posts: 13
Joined: Sat Dec 01, 2012 2:06 pm
x 1

Re: createAnimationState not animating

Post by TheComet »

Thanks, that helped a lot!

I ended up writing the following method to extract a section of an animation:

Code: Select all

// ----------------------------------------------------------------------------
void Entity::extractAnimation(Ogre::Animation* source,
                              Ogre::Animation* dest,
                              Ogre::Real startTime,
                              Ogre::Real endTime)
{
    // NOTE: Might want to check that startTime and endTime are valid

    Ogre::Real timeScale = dest->getLength() / (endTime - startTime);

    // loop through all animation node tracks in source and copy them to destination
    for(Ogre::Animation::NodeTrackIterator srcNodeTrackIt = source->getNodeTrackIterator();
        srcNodeTrackIt.hasMoreElements()
        ;)
    {
        Ogre::NodeAnimationTrack* srcNodeTrack = srcNodeTrackIt.getNext();
        unsigned short trackHandle = srcNodeTrack->getHandle();
        Ogre::NodeAnimationTrack* destNodeTrack = dest->createNodeTrack(trackHandle);

        // loop through all transforms of current source track and copy them to destination
        // if they are within the time frame specified
        for(unsigned short keyFrameHandle = 0;
            keyFrameHandle != srcNodeTrack->getNumKeyFrames();
            ++keyFrameHandle)
        {
            Ogre::TransformKeyFrame* srcKeyFrame = srcNodeTrack->getNodeKeyFrame(keyFrameHandle);
            if(srcKeyFrame->getTime() < startTime || srcKeyFrame->getTime() > endTime)
                continue;

            Ogre::Real scaledTime = (srcKeyFrame->getTime()-startTime) * timeScale;
            Ogre::TransformKeyFrame* destKeyFrame = destNodeTrack->createNodeKeyFrame(scaledTime);

            destKeyFrame->setTranslate(srcKeyFrame->getTranslate());
            destKeyFrame->setRotation(srcKeyFrame->getRotation());
            destKeyFrame->setScale(srcKeyFrame->getScale());
        }
    }
}
Post Reply