"Turn" using OGRE 3D Motion Model-----OGRE 3D 1.7 beginner ' s Guide Chinese version fifth

Source: Internet
Author: User

  

The focus of this chapter will be on model actions and how they usually work, especially in the ogre 3D. There is no movement, so a 3D scene is lifeless. Exercise is one of the most important factors that make the scene realistic and interesting.

In this chapter, we will:

※ Play a sport.

※ Combine the two movements together.

※ related entities on the sport.

One. "Add Motion"

In the previous chapters, we added the interactivity of the program using user input. Now we are going to add a movement to increase the interactivity of another form. Exercise is a very important factor for each scene. Without them, each scene will appear to be stationary and lifeless, but the scene will be vivid when added to the movement. So let's add them.

As always, we'll use the code from the previous chapters, but this time we're not going to delete anything.

1. For our movement, we need to add a new member variable to the frame listener. Add a pointer to store the entity we want to move, and another pointer to save the motion state:

ogre::entity* _ent;ogre::animationstate* _anistate;

2. Then change the frame listener's constructor to take the pointer of the entity 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 entity pointer of the parameter to the new member variable: "

_ent = ent;

4. After this, the dance action is called from the entity and stored in the member variable created specifically for it. Finally, set the motion to Enabled and loop the motion.

_anistate = _ent->getanimationstate ("Dance"); _anistate->setenabled (true); _anistate->setloop (true);

5. Then we need to tell the movement how long it has been since the last update. We will add this to the framestarted () function, and through this we can.

_anistate->addtime (Evt.timesincelastframe);

6. The last thing we need to do is adjust the Exampleapplication class so that it works with the new frame listener. Add a new member variable to the program to hold an entity pointer.

ogre::entity* _sinbadent;

7. Assign the original created local pointer to the newly created entity for storage. Put

ogre::entity* Sinbad = Mscenemgr->createentity ("Sinbad", "Sinbad.mesh");

Replaced by

_sinbadent = Mscenemgr->createentity ("Sinbad", "Sinbad.mesh");

8. The same changes need to be made when associating entities to nodes.

_sinbadnode->attachobject (_sinbadent);

9. Of course, when creating a new frame listener, add a new parameter to the calling constructor.

ogre::framelistener* Framelistener = new Example34framelistener (_sinbadnode,_sinbadent,mwindow,mcamera);

10. Compile and run the program. You're going to see Sinbad dancing.

"What just happened?" 】

With just a few lines of code, we realized the Sinbad beat. In the first step, we add two member variables for the motion model. The first pointer variable is the user storage model. The second ogre::animationstate pointer variable, used by Ogre 3D to describe a single motion and its associated information. The second and third steps are easier to understand, and the second step is to change the constructor to accommodate the new pointer, and the third step is to save the member variables created in the first step. The fourth step is more interesting, and we ask the entity to return to our campaign called "Dance". Each entity variable holds all the movement of the entity itself, and we can use the string variable and the Getanimationstate () function to query the motion. This function returns the Animationstate pointer of the motion, and if the motion is empty, it returns a null pointer. After getting the state of the motion, we activate it.

This tells Ogre 3D to play this action. Again, we set the Loop property to true so that the action can be looped back until we stop it. The fifth step is an important step in using this line of code to bring the entity to life. Each time the scene is rendered, then add the motion time so that the ogre 3D is ready to play. To be exact, it corresponds to the past time from the previous frame to the present. This may have to be done by Ogre 3D itself, but this way is more flexible. For example, we can add a second model, but we want it to do a slow motion. If the ogre 3D itself updates the action, then the motion of the model will be very difficult for us, whether at normal speed or at a slow speed. But we do it ourselves, we can put evt.timesincelastframe *0.25 and we can achieve slow motion. After this step, you can make minor modifications to the constructor, making it compatible with the frame listener's constructor. In this way, we need to save the entity pointer that we want to move.

"Simple test--the importance of Time"

Why do we need to tell Ogre 3D how much has elapsed since the last update to the present time? What are the advantages of this approach?

Two. "Simultaneous control of two actions"

Add a second model, which stands next to the first model, but moves in a slow motion. You should see two models showing different stages of motion, as shown in the following picture:

After adding our first action, we'll look at why and how to play the action at the same time.

Here, we will add a second action using the same method as the first example:

1. From dance, change movement to RunBase.

_anistate = _ent->getanimationstate ("RunBase");

2. Compile and run the program. You can see the Sinbad running, but only the upper body is not moving in situ.

3. For our second action, we need a new pointer to save the state of motion:

Ogre::animationstate* _anistatetop;

4. Then, we need to get the state of motion, activate and cycle the motion. We need to call the motion name Runtop.

_anistatetop = _ent->getanimationstate ("Runtop"); _anistatetop->setenabled (true); _anistatetop->setloop ( true);

5. The last thing to do is add the time from the previous frame, as we set it for the first time:

_anistatetop->addtime (Evt.timesincelastframe);

6. Then compile and run the program. Now you can see Sinbad the whole body doing the running action.

"What just happened?" 】

We have used two movements at the same time. Before, if you ask yourself why you don't call a function like Playanimation (animationname), you need to get animationstate to play the motion. Now you have the answer. Ogre 3D supports multiple movements at the same time, but using playanimation (animationname) does not work. We can even control the model at different speeds by using a modified variable and the Addtime () function.

Three. "Let our model take two steps."

We already have a walking movement, but the model doesn't change its position. We will add the underlying model motion control and use what we have learned to blend the motion.

As always, we will use the previous code as a starting point:

1. First, we need two variables in frame monitoring to control the movement and save the rotation.

float _walkingspeed;float _rotation;

2. In the constructor, we initialize a new variable; we move 50 units per second and start with no rotation:

_walkingspeed =50.0f;_rotation =0.0f;

3. Then we need to change the state of motion and stop it from looping. This time, when the new movement starts, we need to control the model rather than handing it over to the Ogre 3D control.

_anistate = _ent->getanimationstate ("RunBase"); _anistate->setloop (false); _anistatetop = _ent-> Getanimationstate ("Runtop"); _anistatetop->setloop (false);

4. In the Framestarted () method, we need two local variables, one to show whether we have moved the model, and the second to save the direction of the model movement.

BOOL walked = False;ogre::vector3 sinbadtranslate (0,0,0);

5. Also in the method, we add new code to control the movement of the model. We will use the arrow keys to move. When a key is pressed, we need to save the transformation variable to store the direction of the model move, and we need to set the rotation variable in the direction it moves to rotate the model

if (_key->iskeydown (ois::kc_up)) {    Sinbadtranslate + = Ogre::vector3 (0,0,-1);    _rotation =3.14f;    walked = true;}

6. We need to add three additional directional keys in the same way:

if (_key->iskeydown (Ois::kc_down)) {    Sinbadtranslate + = Ogre::vector3 (0,0,1);    _rotation =0.0f;    walked = true;} if (_key->iskeydown (Ois::kc_left)) {    Sinbadtranslate + = Ogre::vector3 ( -1,0,0);    _rotation =-1.57f;        walked = true;} if (_key->iskeydown (ois::kc_right)) {    Sinbadtranslate + = Ogre::vector3 (1,0,0);    _rotation =1.57f;    walked = true;}

7. Then, after pressing the key, we need to check if walked is true in this frame. If this is the case, we need to check whether the motion stops. When True, we re-start the movement:

if (walked) {    _anistate->setenabled (true);    _anistatetop->setenabled (true);    if (_anistate->hasended ())    {        _anistate->settimeposition (0.0f);    }    if (_anistatetop->hasended ())    {        _anistatetop->settimeposition (0.0f);}     }

8. If we do not move this frame, we need to set two motion state to 0. Otherwise, our model will look as if it were frozen in half the way it was done, and that doesn't look good. So if we don't need to walk in this frame, we need to set two movements back to their starting position. Similarly, when this frame does not move the model, we will freeze two motions, because at this point we do not need to exercise.

else{       _anistate->settimeposition (0.0f);       _anistate->setenabled (false);       _anistatetop->settimeposition (0.0f);       _anistatetop->setenabled (false);}

9. The last thing we need to do is apply transformations and rotate the scene nodes to the model:

_node->translate (Sinbadtranslate * Evt.timesincelastframe * _ Walkingspeed); _node->resetorientation (); _node- >yaw (Ogre::radian (_rotation));

10 now we compile and run the program. Under the action of the mouse and WASD keys, we can move the camera. With the arrow keys, we can move the Sinbad. Every time he moves, he makes the right move.

"What just happened."

We combined user input and motion to create the first program. This can be called the first real interactive program we have so far. In the first and second steps, we create and initialize the variables we need. In the third step, we changed the way we used to move, and to be precise, we used to activate the movement directly and loop it. Now we do not want to activate it directly, because we only need to use the movement when moving, in addition to the situation, it looks very stupid. This is why we freeze the cycle of movement. We just want to reflect the user's input, so there's no need to keep looping. If necessary, we will start the exercise ourselves.

We are basically the changes made in the framestarted () method. In the fourth step, we created a pair of local variables to be used later. One is to indicate whether this frame model moves the switch of type bool, and the other is a vector that represents the direction of movement. The status of the direction keys is queried in steps fifth and sixth. When a key is pressed, we change the direction vector, do the corresponding rotation and set the move switch to true. In the seventh step we use this switch, if flag is true, meaning that the frame model will move, we activate the motion and check if there is movement to reach their end. If the movement reaches the end, we reset them to the starting point so that they can continue playing again. Because when the model doesn't move, we don't want to play the motion, so in the eighth step we set them as the starting point and freeze them. In the Nineth step, we applied the transformation. Then reset the rotation, after which the new rotation is applied. This step is necessary because the yaw function adds rotation to the existing rotation, and we need absolute rotation instead of relative rotation. Therefore, we reset the rotation first and apply the rotation to the current zero rotation.

Four. "Add Double knife"

We now have a model that can control walking and motion through user input. Now we are going to look at how we add an object to the motion model.

1. After the Createscene function, create an instance of the two knife models and name them Sword1 and Sword2:

ogre::entity* sword1 = mscenemgr->createentity ("Sword1", "Sword.mesh"); ogre::entity* Sword2 = mscenemgr-> Createentity ("Sword2", "Sword.mesh");

2. Now use a name to correlate the knife to the model:

_sinbadent->attachobjecttobone ("Handle.l", Sword1); _sinbadent->attachobjecttobone ("HANDLE.R", Sword2);

3. Compile and run the program. You will see that Sinbad has two knives in his hand.

"What just happened?" 】

We created instances of the two knives and associated them to the bones. The created instance is not difficult to understand. The more difficult but interesting part of the code just now calls the function Attachobjecttobone (). To understand how this function works, we need to discuss how the motion is saved and played.

X movement

For exercise, we use something called skeletons (skeleton) and bones (skeleton). The system is inspired by nature, and in nature, almost all living creatures have a skeleton to support it. With the help of skeletons and some muscles, animals and humans can move a part of their body in a definite direction. For example, we can use the joints of our fingers to hold our fingers in a fist. Motion in computer graphics is also run in the same way. The artist defines the 3D model and creates a skeleton for it so that the model can move. The skeleton is composed of bones and joints. The joints are connected to two bones and define the direction of movement of the bones. Here is a simplified skeleton diagram, and usually much more than here.

With the radius of the joints, bones and bones, an artist can create complex motions, such as the Sinbad movement we are using. It's like exercise, and bones have names. Ogre 3D Let's use these bones as points for the associated entities. This has a huge advantage, and when the entity is associated, the body is rotated like a bone, which means that if we have an association point in the Sinbad's hand and the knife is connected, the double knife will always be in the hand. Because when the hands do the action, the knife will also get the same movement. If this function does not exist, it is almost impossible to add a model to the hand or to relate things to their back, as we do with the knife.

Five. "Print out all the actions of the model"

We already know that the artist defines the name of the movement, but many times it is important to get the name of the movement directly from the ogre 3D. It is important to get a name when we do not have the art of making this model to ask if there is any movement in it or if you want to check the success of the exported processing. Now we'll look at how to print all the motion of the model in the console.

We will use the previous code as a starting point to print all the motion of our entity.

1. At the end of the Createscene () function, use set to get all the motion of the model:

ogre::animationstateset* set = _sinbadent->getallanimationstates ();

2. Then define an iterator and initialize it with a set iterator:

Ogre::animationstateiterator iter = set->getanimationstateiterator ();

3. And, finally, iterate through all the actions and print their names:

while (Iter.hasmoreelements ()) {std::cout << iter.getnext ()->getanimationname () << Std::endl;}

4. Compile and run the program. After you start the program and load the scene, you will see the following text in the console program.

Dance

Drawswords

Handsclosed

Handsrelaxed

Idlebase

Idletop

Jumpend

Jumploop

JumpStart

RunBase

Runtop

Slicehorizontal

Slicevertical

"What just happened?" 】

We request that the entity return to us a dataset containing motion information. We then traverse the dataset and print out the name of the motion. We see a lot of unused and already used sports.

"Chapter Review"

In this chapter we learn a lot about sports and how to use it to make our 3D more interesting methods.

Specifically, what we have learned covers the following:

※ How to get the motion of the entity and use it.

※ How to activate, Freeze and cycle the program and why you need to tell the movement how long it has been since the last frame.

※ How to use two sports at the same time.

※ How does the movement use the skeleton? How do I associate an entity to a bone?

※ How to query all the movements contained in the entity.

In the next chapter, we'll look at another new aspect of Ogre 3D, mainly about using different scene managers and why.

"Turn" using OGRE 3D Motion Model-----OGRE 3D 1.7 beginner ' s Guide Chinese version fifth

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.