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

Time for action — translating in World space

We are going to move an object in a different way from what we are used to.

  1. Again, start with an empty createScene() function; so delete every code you have in this function.
  2. Create a reference object:
    Ogre::Entity* ent = mSceneMgr->createEntity("MyEntity","Sinbad.mesh");
    Ogre::SceneNode* node = mSceneMgr->createSceneNode("Node1");
    node->setPosition(0,0,400);
    node->yaw(Ogre::Degree(180.0f));
    mSceneMgr->getRootSceneNode()->addChild(node);
    node->attachObject(ent);
    
  3. Create two new instances of the model and translate each one with (0,0,10):
    Ogre::Entity* ent2 = mSceneMgr->createEntity("MyEntity2","Sinbad.mesh");
    Ogre::SceneNode* node2 = node->createChildSceneNode("node2");
    node2->setPosition(10,0,0);
    node2->translate(0,0,10);
    node2->attachObject(ent2);
    Ogre::Entity* ent3 = mSceneMgr->createEntity("MyEntity3","Sinbad.mesh");
    Ogre::SceneNode* node3 = node->createChildSceneNode("node3");
    node3->setPosition(20,0,0);
    node3->translate(0,0,10);
    node3->attachObject(ent3);
    
  4. Compile and run the application. Navigate the camera until you see the previous models like the following:
    Time for action — translating in World space
  5. Replace the line:
    node3->translate(0,0,10);
    

    with

    node3->translate(0,0,10,Ogre::Node::TS_WORLD);
    
  6. Again, compile and run the application and navigate the camera like before.
    Time for action — translating in World space

What just happened?

We used a new parameter of the translate() function. The result was that the left model in the scene moved in a different direction to the middle model.

Different spaces in a 3D scene

The reason why the model moved differently is because with Ogre::Node::TS_WORLD, we told the translate() function that the translate should happen in world space and not in parent space, where it is normal. There are three kinds of spaces we have in a 3D scene – world space, parent space, and local space. Local space is where the model itself is defined. A cube consists of eight points and can be described as in the following diagram:

Different spaces in a 3D scene

The black point is the null point of local space. Each point of the cube is described as a translate from the null point. When the scene is rendered, the cube needs to be in world space. To get the cube in world space, all transformations of these parents in the scene graph are applied to these points. Let's say the cube is attached to a scene node which is added to the root scene node with a translate of (10,0,0). Then the world space with the cube would look like this:

Different spaces in a 3D scene

The difference between the two cubes is that the null point has shifted its position, or to be more precise, the cube has been moved away from the null point.

When we call the translate() function, the cube is moved in parent space if the space to use is not defined, like we did in step 5. When no parent of the cube is rotated, translate() behaves the same way with world space as it would when used with parent or local space. This is true because only the position of the null point changes and not the orientation of the axes. When we, say, move the cube (0,0,10) units, it doesn't matter where the null point is as long as the axes of the coordination system are orientated the same, it won't change the outcome of the translate process. However, when a parent is rotated, this is no longer true. When the parent is rotated, this also rotates the axis of the null point, which changes the meaning of translate(0,0,10).

Different spaces in a 3D scene

The left coordination system is not rotated and (0,0,10) means moving the cube 10 units nearer to the viewer. This is because the z-axis is pointing out of the screen. With the 180 degree rotation, (0,0,10) means moving the cube 10 units away from the viewer because the z-axis is pointing into the screen.

We see that it is important in what space we describe the translate() function to get the desired effect. World space always has the same orientation of axis. To be precise, world spaces uses the left coordination system. Parent space uses a coordination system where all rotations from the parent upwards are applied. Local space includes all rotations, from the scene node itself to all parents. The default setting of translate() is to use parent space. This enables us to rotate the node itself without changing the direction a node moves when using translate(). But there are cases when we want to translate in a space different to parent space. In such cases, we can use the second parameter from translate(). The second parameter specifies the space we want the translate to happen in. In our code, we used Ogre::Node::TS_WORLD to move the model in world space, which inverted the direction the model used because we rotated the node around 180 degrees, and with this, flipped the direction of the x-and z-axis. Again, look at the image to see the effect.