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.37 PositionInterpolator

PositionInterpolator { 
  eventIn      SFFloat set_fraction        # (-INF,INF)
  exposedField MFFloat key           []    # (-INF,INF)
  exposedField MFVec3f keyValue      []    # (-INF,INF)
  eventOut     SFVec3f value_changed
}

The PositionInterpolator node linearly interpolates among a list of 3D vectors. The keyValue field shall contain exactly as many values as in the key field.

"2.6.8 Interpolators" contains a more detailed discussion of interpolators.

TIP: A PositionInterpolator can be used to animate any SFVec3f value, but for some values the interpolation calculation done by the PositionInterpolator will not give the best results. For example, you can use a PositionInterpolator to make an object change size by routing it to a Transform's set_scale eventIn. However, scaling is a logarithmic operation, and the linear interpolation done by the PositionInterpolator will give nonintuitive results. Imagine you are making an object go from one-quarter its normal size to four times its normal size. An interpolator that maintained a constant rate of growth would make the object normal size halfway through the animation. A PositionInterpolator, however, would make the object
        .25 + (4 - .25)/2 = 2.125

halfway through, resulting in rapid growth at the beginning of the animation and very slow growth at the end. A ScaleInterpolator that would look exactly like a PositionInterpolator but perform a different interpolation calculation was considered, but animation of scale isn't common enough to justify adding another node to the specification.


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: When creating a PositionInterpolator make sure to specify key values (e.g., time) that produce desirable velocities. For example, if you want constant velocity you must choose key times that are spaced proportionally to the distances between the keyValues. For each key[i], calculate the linear distance from the first keyValue[0] to the current keyValue[i] (making sure to go through all of the points between keyValue[0] and keyValue[i]), and divide this by the length of the entire keyValue sequence:

   PositionInterpolator {
     key [ 0.0, .0909, 1.0 ]
     # where key[1] = .0909
     #              = (length[i]/total length) = 9/99)
     keyValue [ 1 0 0, 10 0 0, 100 0 0 ]
   }

EXAMPLE (click to run) : The following example illustrates a simple case of the PositionInterpolator node. A PositionInterpolator is routed to a Transform that contains a Cone. When the Cone is clicked it fires the TouchSensor, which starts the TimeSensor, which drives one complete cycle of the PositionInterpolator:

#VRML V2.0 utf8
  Group { children [
  DEF PI PositionInterpolator {
    key [ 0.0, .1, .4, .7, .9, 1.0 ]
    keyValue [ -3 0 0, 0 0 0, 0 20 -50, 0 0 -100, 
                0 0 0, -3 0 0 ]
  }
  DEF T Transform {
    translation -3 0 0 
    children Shape {
      geometry Cone {}
      appearance Appearance {
        material Material { diffuseColor 1 0 0 }
      }
    }
  }
  DEF TOS TouchSensor {}                  # Click to start
  DEF TS TimeSensor { cycleInterval 3.0 } # 3 sec loop
  Background { skyColor 1 1 1 }
  NavigationInfo { type "EXAMINE" }
 ]}
 ROUTE PI.value_changed TO T.translation
 ROUTE TOS.touchTime TO TS.startTime
 ROUTE TS.fraction_changed TO PI.set_fraction