The Annotated VRML 97 Reference

1 Intro     Concepts     3 Nodes     4 Fields/Events    Conformance
A Grammar     B Java     C JavaScript     D Examples     E Related Info    References
Quick Java         Quick JavaScript         Quick Nodes   
 

  About the Book
  
Help
  Copyright © 1997-99
  Purchase the book from Amazon.com

Chapter 3:
Node Reference


Intro
Anchor
Appearance
AudioClip
Background
Billboard
Box
Collision
Color
ColorInterpolator
Cone
Coordinate
CoordinateInterpolator
Cylinder
CylinderSensor
DirectionalLight
ElevationGrid
Extrusion
Fog
FontStyle
Group
ImageTexture
IndexedFaceSet
IndexedLineSet
Inline
LOD
Material
MovieTexture
NavigationInfo
Normal
NormalInterpolator
OrientationInterpolator
PixelTexture
PlaneSensor
PointLight
PointSet
PositionInterpolator
ProximitySensor
ScalarInterpolator
Script
Shape
Sound
Sphere
SphereSensor
SpotLight
Switch
Text
TextureCoordinate
TextureTransform
TimeSensor
TouchSensor
Transform
Viewpoint
VisibilitySensor
WorldInfo

+3.32 OrientationInterpolator

OrientationInterpolator { 
  eventIn      SFFloat    set_fraction      # (-INF,INF)
  exposedField MFFloat    key           []  # (-INF,INF)
  exposedField MFRotation keyValue      []  # [-1,1],(-INF,INF)
  eventOut     SFRotation value_changed
}

The OrientationInterpolator node interpolates among a set of rotation values specified in the keyValue field. These rotations are absolute in object space and therefore are not cumulative. The keyValue field shall contain exactly as many rotations as there are keyframes in the key field.

An orientation represents the final position of an object after a rotation has been applied. An OrientationInterpolator interpolates between two orientations by computing the shortest path on the unit sphere between the two orientations. The interpolation is linear in arc length along this path. If the two orientations are diagonally opposite results are undefined.

If two consecutive keyValue values exist such that the arc length between them is greater than PI, the interpolation will take place on the arc complement. For example, the interpolation between the orientations (0, 1, 0, 0) and (0, 1, 0, 5.0) is equivalent to the rotation between the orientations (0, 1, 0, 2PI) and (0, 1, 0, 5.0).

A more detailed discussion of interpolators is contained in "2.6.8 Interpolators."

TIP: The OrientationInterpolator, like all of the other interpolators, interpolates between a series of poses. The keyframes that define each pose do not encode any information about how the object got into that pose. This makes it tricky to create an OrientationInterpolator that rotates an object 180 degrees or more, because the keyframes must be thought of as a static orientation of an object, and not as an axis to rotate about and an angle rotation amount. Confusion arises because the representation chosen for orientations is the axis and angle that the object must be rotated around to bring it from its default orientation to the desired orientation. However, that conceptual movement has no relation to the movement of an object between orientation keyframes, just like the conceptual movement of an object from (0,0,0) to a position keyframe has no relation to the movement between keyframes. It is easy to think that an orientation keyframe of (0,1,0,6PI) means "perform three complete rotations about the Y-axis." It really means "the orientation that results when the object is rotated three complete times about the Y-axis," which is exactly the same orientation as zero (or one or two or three) rotations about the Y-axis, and it is exactly the same orientation as six (or zero) complete rotations about any other axis. More than one keyframe must be specified to perform a rotation of 180 degrees (PI radians) or greater. In general, to specify N complete rotations of an object you must specify 3N +1 keyframes, each spaced 120 degrees apart. For example, an OrientationInterpolator that rotates an object all the way around the Y-axis as it receives set_fraction events from 0.0 to 1.0 can be specified as:

  OrientationInterpolator {
    key [ 0  0.333  0.666 1 ]
    keyValue [ 0  0 1 0    # Start with identity.
                           # Same as  0 1 0 0.
               0  1 0 2.09 # Oriented 120 deg Y
               0 -1 0 2.09 # Oriented 120 deg -Y
                           # Same as 0 1 0 4.18
               0  0 1 0 ]  # End up where we started
  }

TIP: Remember that TimeSensor outputs fraction_changed events in the 0.0 to 1.0 range and that interpolator nodes routed from TimeSensors should restrict their key field values to the 0.0 to 1.0 range to match the TimeSensor output and thus produce a full interpolation sequence.

TIP: Remember that rotations in VRML are specified as an axis vector and an angle, and that the angle is specified in radians, not degrees. Radians were chosen in the Open Inventor tool kit for their programming convenience and were, unfortunately (less familiar than degrees), inherited when we created VRML.

TIP: When creating an OrientationInterpolator, make sure to specify key values (i.e., time) that produce desirable rotation velocities. For example, if you want constant rotational velocity you must choose key times that are spaced identically to the spacing of the rotations in keyValues. First, specify all of the keys to be identical to the keyValues and then divide each key by the maximum keyValue:

OrientationInterpolator {
  key [          0.0,      0.286,       .857,    1.0 ]
  # where key[1] = .286 = keyValue[1] / max(keyValue)
  # where key[2] = .857 = keyValue[2] / max(keyValue
  keyValue [ 0 0 1 0, 0 0 1 1.0, 0 0 1 3.0, 0 0 1 3.5]
}

TIP: Remember that the OrientationInterpolator takes the shortest rotational path between keyframe values and that it is often necessary to insert extra keyframe values to ensure the desired rotations. For example, the following OrientationInterpolator will first rotate counterclockwise 0.523 radians (30 degrees) about the Z-axis and then reverse direction and rotate clockwise to -0.523 radians (330 degrees):

     OrientationInterpolator {
       key [ 0.0 0.5 1.0 ]
       keyValue [ 0 0 1 0, 0 0 1 0.523, 0 0 1 -.523 ]
     }

However, if the desired rotation is to complete a full revolution, rather than reversing direction, an extra keyframe value must be inserted:

     OrientationInterpolator {
       key [ 0 0.33 0.66 1.0 ]
       keyValue [ 0 0 1 0, 0 0 1 0.523,
                  0 0 1 3.14, 0 0 1 -.523 ]
     }

EXAMPLE (click to run): The following example illustrates the use of the OrientationInterpolator node. A TouchSensor is used to trigger the start of the interpolation by routing to a TimeSensor, which is routed to the OrientationInterpolator. The OrientationInterpolator is routed to the rotation field of a Transform:

#VRML V2.0 utf8
Group { children [
  DEF OI OrientationInterpolator {
    key [ 0.0, 0.1, 0.3, 0.6, 0.8, 1.0 ]
    keyValue [ 0 0 1 0, 0 0 1 1.2,
               0 0 1 -1.57, 0 0 1 1.5,
               0 0 1 3.15, 0 0 1 6.28 ]
  }
  DEF T Transform {
    children Shape {
      geometry Cone {}
      appearance Appearance {
        material Material { diffuseColor 1 0 0 }
      }
    }
  }
  DEF TOS TouchSensor {}  # Click to start
  DEF TS TimeSensor {     # Drives the interpolator
       cycleInterval 3.0     # 3 second interp loop
  }
  Background { skyColor 1 1 1 }
] }
ROUTE OI.value_changed TO T.rotation
ROUTE TOS.touchTime TO TS.startTime
ROUTE TS.fraction_changed TO OI.set_fraction