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.46 Switch

Switch { 
  exposedField    MFNode  choice      []
  exposedField    SFInt32 whichChoice -1    # [-1,INF)
}

The Switch grouping node traverses zero or one of the nodes specified in the choice field.

"2.6.5 Grouping and children nodes" describes details on the types of nodes that are legal values for choice.

The whichChoice field specifies the index of the child to traverse, with the first child having index 0. If whichChoice is less than zero or greater than the number of nodes in the choice field, nothing is chosen.

All nodes under a Switch continue to receive and send events regardless of the value of whichChoice. For example, if an active TimeSensor is contained within an inactive choice of an Switch, the TimeSensor sends events regardless of the Switch's state.

design note

Note that the Switch node is a grouping node, so it can't be used in place of an Appearance or Material node to switch between different appearances or textures. Allowing a node to act like several different node types causes implementation difficulties, especially for object-oriented implementations that create a hierarchy of node classes. If Switch could appear anywhere in the scene, implementations would have to be prepared to treat it as a group or a geometry or a material or any other node class.

tip

A Switch node can be used to hide or "comment-out" parts of the scene, which can be useful when you are creating a world and want to turn parts of it off quickly. Just replace any Group or Transform with
     Switch { choice Group/Transform ... } 
The default value for the whichChoice field is –1, so the Group/Transform will not be displayed.
If you need to switch between different textures or materials for a Shape, there are a couple of ways of doing it. The obvious way
     # THIS EXAMPLE IS ILLEGAL!
     Shape {
       appearance Appearance {
        material DEF ILLEGAL Switch {  # Switch is NOT a material!
           choice [
             # Materials are NOT legal children!
             DEF M1 Material { ... }
             DEF M2 Material { ... }
           ]
         }
       }
       geometry IndexedFaceSet ...
     }
does not work, because Switch nodes are not materials, and Material nodes are not legal children nodes. Instead, you can switch between two different shapes that share parts that aren't changing with DEF/USE, like this:
     Switch {
       choice [
         Shape {
           appearance Appearance {
             material DEF M1 Material { ... }
           }
           geometry DEF IFS IndexedFaceSet ...
         }
         Shape {
           appearance Appearance {
             material DEF M2 Material { ... }
           }
           geometry USE IFS  # Same geometry, different material
         }
       ]
     }
Or, alternatively, you can write a Script that changes the Material node directly. For example, here is a prototype that encapsulates a Script that just toggles a Material between two different colors based on an SFBool eventIn:
     PROTO ToggleMaterial [
       field SFColor color1 1 1 1  # White and
       field SFColor color2 0 0 0  # black by default
       eventIn SFBool which ]
     {
       DEF M Material { }
       DEF S Script {
         field SFColor color1 IS color1
         field SFColor color2 IS color2
         eventIn SFBool which IS which
         eventOut SFColor color_changed
         url "javascript:
           function initialize() {
             color_changed = color1;
           }
           function which(value) {
             if (value) color_changed = color2;
             else color_changed = color1;
           }"
       }
       ROUTE S.color_changed TO M.set_diffuseColor
     }
     # Use like this:
     Group {
       children [
          Shape {
           appearance Appearance {
             material DEF TM ToggleMaterial {
               color1 1 0 0  color2 0 1 0
             }
           }
           geometry Cube { }
         }
         DEF TS TouchSensor { }
       ]
       ROUTE TS.isOver TO TM.which
     }

tip

Bindable nodes (Background, Fog, NavigationInfo, and Viewpoint) are not bound by setting their parent Switch's whichChoice field and have no effect on whether a bindable node is active or not. For example, the following file excerpt has a Switch node that has activated the second choice (whichChoice 1). However, the first choice is the first encountered Background node in the file and is bound at load time (i.e., whichChoice has no effect on binding):
     ...
     Switch {
       whichChoice 1      # sets second choice, B2, as active
       choice [
         DEF B1 Background { ... }  # choice 0 bound at load time
         DEF B2 Background { ... }   # choice 1 not bound at load time
         DEF B3 Background { ... }  # choice 2
         ...
       ]
     }
     ...

example

The following example illustrates a simple use of the Switch node (see Figure 3-55). A TouchSensor is routed to a Script, which cycles through the whichChoice field of the Switch node:
#VRML V2.0 utf8
Group { children [
  DEF SW Switch {
    whichChoice 0  # set by Script
    choice [
      Shape {                # choice 0
        geometry Box {}
        appearance DEF A1 Appearance {
          material Material { diffuseColor 1 0 0 }
        }
      }
      Shape {                # choice 1
        geometry Sphere {}
        appearance DEF A1 Appearance {
          material Material { diffuseColor 0 1 0 }
        }
      }
      Shape {                # choice 2
        geometry Cone {}
        appearance DEF A1 Appearance {
          material Material { diffuseColor 0 0 1 }
        }
      }
    ]
  }
  DEF TS TouchSensor {}
  DEF SCR Script {          # Switches the choice
    eventIn SFTime touchTime
    eventOut SFInt32 whichChoice
    url "javascript:
      function initialize() {
        whichChoice = 0;
      }
      function touchTime( value, time) {
        if ( whichChoice == 2 ) whichChoice = 0;
        else ++whichChoice;
      }"
  }
  NavigationInfo { type "EXAMINE" }
]}
ROUTE TS.touchTime TO SCR.touchTime
ROUTE SCR.whichChoice TO SW.whichChoice

Switch node example

Figure 3-55: Switch Node Example