Time for action — adding animations

As always, we are going to use the code from the previous chapter, and for once we don't need to delete anything:

  1. For our animation, we need to add new member variables in the FrameListener. Add a pointer holding the entity we want to animate and a pointer to the used animation state:
    Ogre::Entity* _ent;
    Ogre::AnimationState* _aniState;
    
  2. Then change the constructor of the FrameListener to get the entity pointer as a new parameter:
    Example34FrameListener(Ogre::SceneNode* node,Ogre::Entity* ent,RenderWindow* win,Ogre::Camera* cam)
    
  3. In the function body of the constructor, assign the given entity pointer to the new member variable:
    _ent = ent;
    
  4. After this, retrieve the animation state called Dance from the entity and store it in the member variable we created for this purpose. Finally, set the animation to be enabled and loop it:
    _aniState = _ent->getAnimationState("Dance");
    _aniState->setEnabled(true);
    _aniState->setLoop(true);
    
  5. Next, we need to tell the animation how much time has passed since it was last updated. We will do this in the frameStarted() method; through this we know how much time has passed:
    _aniState->addTime(evt.timeSinceLastFrame);
    
  6. The last thing we need to do is adjust our ExampleApplication to work with the new FrameListener. Add a new member variable to the application to hold a pointer to the entity:
    Ogre::Entity* _SinbadEnt;
    
  7. Instead of assigning the newly created entity to a local pointer, store it using the member variable. Replace
    Ogre::Entity* Sinbad = mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
    

    with

    _SinbadEnt = mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
    
  8. The same needs to be done when attaching the entity to the node:
    _SinbadNode->attachObject(_SinbadEnt);
    
  9. And of course, when creating the FrameListener, add the new parameter to the constructor call:
    Ogre::FrameListener* FrameListener = new Example34FrameListener(_SinbadNode,_SinbadEnt,mWindow,mCamera);
    
  10. Compile and run the application. You should see Sinbad dancing.
Time for action — adding animations

What just happened?

With a few lines of code, we made Sinbad dance. In step 1, we added two new member variables, which will be needed later for animating the model. The first member variable was simply a pointer to the entity we want to animate. The second was a pointer to Ogre::AnimationState, which is used by Ogre 3D for representing a single animation and its associated information. Steps 2 and 3 are straightforward; we changed the constructor to accommodate the new pointer we needed and in step 3 we stored the pointer in the member variables we created in step 1. Interesting stuff happened in step 4; there we asked the entity to return to us the animation named Dance. Each entity stores all the animations it has and we can query them using a string identifier and getAnimationState(). This function returns a pointer to this animation represented as an AnimationState or if the animation doesn't exist, it will return a null pointer. After we got the animation state, we enabled it. This tells Ogre 3D to play this animation. Also, we set the loop property to true so the animation will be played again and again until we stop it. Step 5 is the important one; with this code, we can make the animation come alive. Each time our scene is rendered, we add a bit of time to the animation and therefore Ogre 3D plays it a bit. To be precise, the bit corresponds to the time passed since the last frame. This could, of course, be done by Ogre 3D itself, but this way the function is much more flexible. As an example, we could add a second model which we want to be animated in slow motion. If Ogre 3D updated the animation itself, it could be difficult or impossible for us to animate one model with normal speed and one in slow motion. With the taken approach, we can add a * 0.25 to the time passed since last frame and the model will be animated in slow motion.

The steps after this are simply small modifications of our application so that it is compatible with the changed FrameListener constructor. For this, we needed to save the pointer to the entity we wanted to animate.

Pop quiz — the importance of time

Why do we need to tell Ogre 3D how much time has passed since the animation was last updated and what are the positive side effects of this architecture?

Have a go hero — adding a second model

Add a second model, which stands besides the first one and let it dance in slow motion. You should see two models at different stages of the same animation, as shown in the following image.

Have a go hero — adding a second model
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.165.234