Ogre 3D 1.7 Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Time for action — scaling a scene node

Once again, we start with the same code block we used before.

  1. Remove all the code from the createScene() function and insert the following code block:
    Ogre::Entity* ent = mSceneMgr->createEntity("MyEntity","Sinbad.mesh");
    Ogre::SceneNode* node = mSceneMgr->createSceneNode("Node1");
    node->setPosition(10,10,0);
    mSceneMgr->getRootSceneNode()->addChild(node);
    node->attachObject(ent);
    
  2. Again, create a new entity:
    Ogre::Entity* ent2 = mSceneMgr->createEntity("MyEntity2","Sinbad.mesh");
    
  3. Now we use a function that creates the scene node and adds it automatically as a child. Then we do the same thing we did before:
    Ogre::SceneNode* node2 = node->createChildSceneNode("node2");
    node2->setPosition(10,0,0);
    node2->attachObject(ent2);
    
  4. Now, after the setPosition() function, call the following line to scale the model:
    node2->scale(2.0f,2.0f,2.0f);
    
  5. Create a new entity:
    Ogre::Entity* ent3 = mSceneMgr->createEntity("MyEntity3","Sinbad.mesh");
    
  6. Now we call the same function as in step 3, but with an additional parameter:
    Ogre::SceneNode* node3 = node->createChildSceneNode("node3",Ogre::Vector3(20,0,0));
    
  7. After the function call, insert this line to scale the model:
    node3->scale(0.2f,0.2f,0.2f);
    
  8. Compile the program and run it, and you should see the following image:
    Time for action — scaling a scene node

What just happened?

We created a scene with scaled models. Nothing special happened until step 3. Then we used a new function, namely, node->createChildSceneNode("node2"). This function is a member function of a scene node and creates a new node with the given name and adds it directly as a child to the node which called the function. In this case, node2 is added as a child to the node.

In step 4, we used the scale() function of the scene node. This function takes a triple (x,y,z), which indicated how the scene node should be scaled. x, y, and z are factors. (0.5,1.0,2.0) means that the scene node should be halved on the x-axis, kept the same on the y-axis, and doubled on the z-axis. Of course, in a really strict sense, the scene node can't be scaled; it only holds metadata which isn't rendered. It would be more precise to say that each renderable object attached to this node would be scaled instead of the scene node itself. The node is only a holder or reference frame for all attached children and renderable objects.

In step 6, we used the createChildSceneNode() function again, but this time with more parameters. The second parameter that this function takes is a triple (x,y,z) which is so often used. Ogre 3D has its own class for it called Ogre::Vector3. Besides storing the triple, this class offers functions which implement the basic operations. They can be done with three dimensional vectors in linear algebra. This vector describes the translate which should be used when the scene node is created. createChildSceneNode() can be used to replace the following lines of code:

Ogre::SceneNode* node2 = mSceneMgr->createSceneNode("Node2");
node->addChild(node2);

or even

Ogre::SceneNode* node2 = mSceneMgr->createSceneNode("Node2");
node->addChild(node2);
node2->setPosition(20,0,0);

The last piece of code can be replaced with

Ogre::SceneNode* node2 = node->createChildSceneNode("Node2",Ogre::Vector3(20,0,0));

If we leave out the Vector3 parameter, we can replace the first piece of code. There are more versions of this function, which we will use later. If you can't wait, take a look at the documentation of Ogre 3D at http://www.ogre3d.org/docs/api/html/index.html.

Besides scale(), there is also setScale(). The difference between these functions is the same as between setPosition() and translate().

Pop quiz — creating child scene nodes

  1. Name two different ways of calling createChildSceneNode().
  2. How could the following line be replaced without using createChildSceneNode()?
    Ogre::SceneNode* node2 = node->createChildSceneNode("node1",Ogre::Vector3(10,20,30));
    

    Note

    This line could be replaced with three lines. The first creates the scene node, the second one translates it, and the third attaches it to the node.

    Ogre::SceneNode* node2 = mSceneMgr->createSceneNode("Node2");
    node2->translate(Ogre::Vector3(10,20,30));
    node->addChild(node2);
    

Have a go hero — using createChildSceneNode()

Refactor all the code you wrote in this chapter to use createChildSceneNode().