Chap. 06A --- Instantaneous Movement

Position, Rotation, and Scale

There are three ways to move an object:

  • Change position: ie, move it north, south, east, west, up, or down.
  • Change scale: make it bigger or smaller.
  • Change rotation: ie, turn it on its axes.

Positioning

Position is stored as three numbers: X,Y,Z. We like to think of the global +X axis as 'East', the global +Y axis as 'North', and the global +Z axis as 'Up.' The units are meters, and objects should be modeled using the appropriate scale.

Each object also has its own "local" axes. If a human character is modeled properly, then the local +X axis is to the character's right, the local +Y axis points in front of the character, and the local +Z axis points up out of the top of the character's head.

You can set the position of a character using many different methods. Probably the simplest is object:setPosition(x,y,z). The X,Y,Z values are interpreted as relative to the global coordinate system: increasing Y moves the character north, increasing X moves the character east, and so forth. However, the setPosition method takes an optional parameter: the name of another object. If this is specified, then the position is relative to the other object. For example, fred:setPosition(0,5,0,alice) positions Fred 5 meters in front of Alice.

Functions that get the position of an object can also be relative: for example, fred:getPosition(alice) returns the position of fred relative to alice. In other words, if Fred is 2 meters in front of Alice and 1 meter to her right, it returns 1,2,0.

Scaling

Scale is stored as three numbers: SX,SY,SZ. These numbers measure the size of the object relative to the object's initial size. So for example, if you set the scale of an object using obj:setScale(2,2,2), it means you made it twice as big as it was initially created.

When you scale a model, be aware that the scaling is relative to the model itself. To understand what this means, imagine enlarging enlarging a character using obj:setScaleZ(2) - this makes him twice as tall. But what if you lay the character down on his back, with his nose pointed upwards before you scale him? The answer is that even though he is lying down with his nose pointing in the Z-direction, scaling him in the Z-axis makes him taller, it doesn’t make his nose longer. No matter his orientation, scaling in the Z-direction makes him taller. That is what is meant by saying that the scaling is relative to the model itself.

Because scaling is always relative to the model itself, scaling commands do not take a "relative-to" argument.

Rotation

Rotation of an object can be controlled in many different ways. The easiest case is when you want the object to remain completely upright while it pivots like a compass. In that simple case, you can use functions like obj:setHeading(h) which takes an angle in degrees (0 north, 90 west, 180 south, 270 east). You can also use obj:setCompassDirection("NE") or the like. These commands only work correctly if the model is modeled correctly (facing north).

Another common thing to do is to tell the object to turn to face another object, using the method "obj:setLookAt(otherobj)". The object will instantaneously rotate to face the other object. You can also say "obj:setLookAt(vec(x,y,z))" to make the object look at any arbitrary point in space.

Another common way is to adjust the object's heading, pitch, and roll using object:setHPR(h,p,r). To understand what these numbers mean, think of an airplane. Roll is when the airplane lowers one wing and raises the other. Pitch is when the airplane raises its nose and lowers its tail, or vice versa. Heading is when the airplane turns north, south, east, or west. The numbers H,P,R are in degrees.

Many of the rotation commands take a relative-to argument. The command fred:setHeading(0, alice) causes fred to face in the same direction as alice. What is slightly surprising about this is that you normally think of "setHeading" as rotating an object within the horizontal plane, like an old-fashioned vinyl record player rotates a record. But when used relative to Alice, the plane of rotation itself is relative to Alice. That is, if Alice is tilted slightly, then it is as if the record player were tilted. If Alice is lying down facing upward, then the setHeading plane of rotation becomes vertical.

Like position-setting operations, rotation-setting operations can be relative to self. For example, fred:setHeading(5,fred) causes Fred to turn 5 degrees to the left of where Fred used to be.

Other Things with Position, Rotation, and Scale

Class 'Transform' is a simple class containing nothing but a position, rotation, and scale field. This class has all the same methods like 'setPosition', 'setHPR', and so forth that move SceneObjects around. In fact, it can be convenient, when searching for a movement method, to look at the documentation for class Transform instead of the documentation for class SceneObject: the same movement methods are all there, without the other clutter.

There are other classes, such as CameraBoom, that also have position, rotation, and scale. All of these classes are called 'transformable' objects. These transformable objects all share the same movement methods. Methods like 'setPosition' that take an optional relative-to argument will accept any transformable class.