Eng 591 - VR Programming - Class Outline 2

General Topics: Coordinate Systems & Placing Objects

Coordinate Systems

  • Right hand axes - X, Y, and Z.

    WorldToolKit uses a right-hand coordinate system. If the fingers of the right hand are pointed along the positive X axis, with the palm facing the positive Y axis, then the thumb points along the positive Z axis. This means that X is normally to the right, Z straight ahead, and Y points DOWN.

    For rotations, if the thumb of the right hand points in the positive direction along an axis, then the fingers curl in the direction of positive rotation about that axis. Note that this applies to axes at any angle, not just the X, Y, and Z coordinate axes.

  • Alternate reference frames.

    Positions, directions, and movement are most often given with respect to a stationary world reference frame. However sometimes it is more useful to move or place objects relative to some other reference frame. For example, you might want to place an object relative to the user ( viewpoint ), or rotate a doorknob relative to its own axis. WorldToolKit has a number of #defined constants that are useful for specifying reference frames.

  • Units

    The units of measure in WTK simulations are not specified as inches, meters, etc. However they must be consistent within a simulation. For example, if you make a doorway seven units high, you probably want your viewpoint around five units high, rather than one unit high. Note: in stereoscopic applications it is important to set the distance between the left-eye and right-eye viewpoints to the same scale. In this example, if the distance between these viewpoints were 30 units, then the house would appear as a doll house.

  • Defined types and constants

    WTK has a number of data types and constants defined for use in setting positions and orientations:

    • typedef float WTp3[ 3 ], WTp2[ 2 ], WTq[ 4 ];
    • typedef float WTm3[ 3 ] [ 3 ], WTm4[ 4 ] [ 4 ];
    • #define X = 0, Y = 1, Z = 2, W = 3, TRUE = 1, FALSE = 0;
  • Overview of available math functions - Chapter 25

Quaternions

There are many different systems available for describing rotations and angles in three-dimensional space. WTK happens to use quaternions, which take the form of a set of four floating point numbers. ( See defintion of WTq above. ) Quaternions can be a little difficult for humans to grasp and work with, but they happen to be very efficient computationally, allowing WTK to perform rotational calculations very quickly.

The general concept behind a quaternion is that for any given change of orientation, there exists a single axis about which the object can be rotated to move from the initial orientation to the final orientation. ( As opposed to rotating about each of the three coordinate axes in some pre-defined order.) Note that the axis of rotation for a quaternion will frequently be some oblique angle, not one of the coordinate axes. The first three numbers of the quaternion provide information regarding the axis of rotation, and the fourth value provides information about how far to rotate about that axis.

The actual procedure for calculating a quaternion is a bit more complicated, as follows:

  1. First determine the axis of rotation, specified as a directional vector.
  2. Normalize the vector, so that its length is 1.0.
  3. Multiply each component of the vector by the sine of ( one half of the angle of rotation. ) The result is the first three components of the quaternion.
  4. The fourth component of the quaternion is the cosine of ( one half of the angle of rotation. )

Example 1: It is desired to swing a door 90 degrees along the axis of its hinges, towards the user ( who is facing the door along the Z axis. ) What is the necessary quaternion?

Solution: The axis of rotation is parallel to the Y axis. Following the right hand rule, it can either be considered as a negative 90 degree rotation about the axis ( 0, 1, 0 ), or a positive 90 degree rotation about ( 0, -1, 0 ). Half of the angle is 45 degrees. Using the positive Y axis, the cosine of 45 is 0.7071, and the sine of ( -45 ) is -0.7071. The resulting quaternion is

( 0, -0.7071, 0, 0.7071 )

Example 2: Hold your right hand in front of your face, palm away from you with your fingers pointing towards the ceiling. Now rotate your hand so that your fingers point towards your left, and your palm faces you. What is the quaternion that corresponds to this rotation?

Solution: The axis of rotation is ( -1, -1, 0 ), and the rotation is 180 degrees. Normalizing the vector requires dividing by the square root of 2.0, yielding ( -0.7071, -0.7071, 0.0 ). Half of the angle is 90 degrees, which has a sine of 1.0 and a cosine of 0.0. The resulting quaternion is

( -0.7071, -0.7071, 0, 0 )

Note that the factor of 0.7071 in the first example came from the sine and cosine of the angle, and in the second example it came from normalizing the axis of rotation.

Example 3: What is the quaternion that corresponds to a rotation of 45 degrees about the direction axis (3, -4, 5)?

Solution: Normalizing the vector requires dividing by the square root of 50.0, yielding (0.4243, -0.5657, 0.7071). Half of the angle is 22.5 degrees, which has a sine of 0.3827 and a cosine of 0.9239. The resulting quaternion is

( 0.1624, -0.0216, 0.2706, 0.9239 )

Introduction to Scene Graphs - Chapter 4 ( book ) & ( Chapter 3 of WTK html )

  • Root and tree structure, with nodes and arcs.
  • Traversal order
  • Node types

Movable Nodes Versus Non-Movable Nodes ( Chapter 5 of WTK_html )

  • Problem with propagation of transformations.
  • Movable node = separator + transform + geometry.
  • WTnode_load
  • WTmovnode_load
  • WTmovnode_instance
  • WTnode_ismovable

Functions For Setting Positions ( Directions )

  • WTnode_settranslation
  • WTnode_gettranslation
  • WTnode_translate
  • WTp3_print
  • WTp3_* math functions
  • WTnode_getmidpoint
  • WTnode_getextents
  • WTlightnode_setdirection

Functions For Setting Orientations

  • WTnode_setorientation
  • WTnode_getorientation
  • WTnode_rotateq ( WTnode_rotatem3, WTnode_rotatem4 )
  • WTq_print
  • WTnode_axisrotation
  • WTnode_rotation
  • WTq_* math functions

Functions For Setting Both Position and Orientation

  • WTviewpoint_moveto
  • WTnode_settransform

Moving Objects Versus Building Them in Place

When you need an object in a particular position and orientation, there are three approachs:
  1. Build the object originally so that it is in the correct place when you load it.
  2. Build the object at the origin, and then move it to its correct location every time you load it.
  3. Build the object at the origin, load it once and move it to its correct location, and then save the object in its new position. Whenever the object is loaded again in the future, it will be in its correct position and will not have to be moved again.

Each of these methods has its advantages and disadvantages, and each can be the "best" approach depending upon several important considerations:

  • Moving an object every time it is loaded takes a certain amount of time. If the object is already in its correct location, then it doesn't need to be moved.
  • If the same object is to be used several times, either within a single simulation or between different simulations, then it should be built at the origin. Otherwise it has to be moved relative to its position in the file, which can be difficult if the original position is not at the origin. ( The solution to this problem is to get the position of the object's center, use that information to move it to the origin, and then move it to its desired location from there. )

Homework / Lab Exercises

  • Make the following modifications to your project program ( bareVR.c ):
    1. Change the direction of the directed light.
    2. Change the clown, snail, and lunchbox to moveable nodes. Set their positions and orientations when they are loaded, so that they are not all located at the same spot. ( Experiment with a variety of methods for doing this. )
    3. Set up a global variable of type WTpq, called InitialView, which will hold the initial user viewpoint position and orientation when the program starts. Modify the action function so that typing either upper or lower case "R" will reset the view to the initial view. ( This can be done either by initializing InitialView and replacing Wtwindow_zoomviewpoint with code to set the viewpoint to the initial view, or by getting the initial viewpoint coordinates after the call to Wtwindow_zoomviewpoint. )