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.54 VisibilitySensor

VisibilitySensor { 
  exposedField SFVec3f center   0 0 0      # (-INF,INF)
  exposedField SFBool  enabled  TRUE
  exposedField SFVec3f size     0 0 0      # [0,INF)
  eventOut     SFTime  enterTime
  eventOut     SFTime  exitTime
  eventOut     SFBool  isActive
}

The VisibilitySensor node detects visibility changes of a rectangular box as the user navigates the world. VisibilitySensor is typically used to detect when the user can see a specific object or region in the scene in order to activate or deactivate some behaviour or animation. The purpose is often to attract the attention of the user or to improve performance.

TIP: A VisibilitySensor detects whether a box-shaped region of the world is visible or not. If you need to find out if an object is visible or not, it is up to you to set the VisibilitySensor's center and size fields so that the VisibilitySensor surrounds the object.

The enabled field enables and disables the VisibilitySensor node. If enabled is set to FALSE, the VisibilitySensor node does not send events. If enabled is TRUE, the VisibilitySensor node detects changes to the visibility status of the box specified and sends events through the isActive eventOut. A TRUE event is output to isActive when any portion of the box impacts the rendered view. A FALSE event is sent when the box has no effect on the view. Browsers shall guarantee that, if isActive is FALSE, the box has absolutely no effect on the rendered view. Browsers may err liberally when isActive is TRUE. For example, the box may affect the rendering.

TECHNICAL NOTE: In other words, it is not OK for a browser to say that something is invisible when it can be seen, but it is OK for a browser to say that something is visible when it actually isn't. The reason the rules are written this way is to allow browser implementors to decide how accurate to make their visibility computations. For example, one implementation might simply calculate whether or not the visibility region is inside or outside the viewer's field-of-view, while another might go further and compute whether or not there is an object in front of the visibility region that completely hides it.

The exposed fields center and size specify the object space location of the box centre and the extents of the box (i.e., width, height, and depth). The VisibilitySensor node's box is affected by hierarchical transformations of its parents. The components of the size field shall be >= 0.0.

The enterTime event is generated whenever the isActive TRUE event is generated, and exitTime events are generated whenever isActive FALSE events are generated.

Each VisibilitySensor node behaves independently of all other VisibilitySensor nodes. Every enabled VisibilitySensor node that is affected by the user's movement receives and sends events, possibly resulting in multiple VisibilitySensor nodes receiving and sending events simultaneously. Unlike TouchSensor nodes, there is no notion of a VisibilitySensor node lower in the scene graph "grabbing" events. Multiply instanced VisibilitySensor nodes (i.e., DEF/USE) use the union of all the boxes defined by their instances. An instanced VisibilitySensor node shall detect visibility changes for all instances of the box and send events appropriately.

TIP: The VisibilitySensor node is often ignored yet excellent tool for managing behavior complexity and rendering performance of your scene. Use the VisibilitySensor to disable interpolators or Scripts when not in view. For example, imagine a file that contains several butterfly swarms that flutter around various flower patches (guided by either interpolators or a Script). Each butterfly swarm can be managed by a VisibilitySensor that encloses the entire swarm and disables the swarm movement when out of view. This is also a good technique for building into behavioral objects or prototypes that you intend to reuse in other files. It establishes good composability principles (objects that manage themselves and do not arbitrarily impact overall world performance).

EXAMPLE (click to run): The following illustrates a simple example of a VisibilitySensor. Two TimeSensors are used to move a Cylinder: one gives it a large motion and one gives it a small motion. A VisibilitySensor is used to disable the small-motion TimeSensor when the object is out of view:

#VRML V2.0 utf8
DEF T1 Transform {  # Large motion transform
  children [
    DEF VS VisibilitySensor {
      # Must be big enough to enclose object
      #plus small motion:
      size 1.6 4.6 1.6
    }
    DEF T2 Transform { # Small motion transform
      children [
        Shape {
          appearance Appearance { material Material { } }
          geometry Cylinder { }
        }
      ]
    }
  ]
}
DEF TS1 TimeSensor { # Large motion TimeSensor
  loop TRUE
  cycleInterval 50
}
DEF PI1 PositionInterpolator {  # Gross movement
  key [ 0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1 ]
  keyValue [ 0 0 -30, -10 5 -20, -20 0 -10, -30 -5 10,
             -20 7 20, -10 4 10, 0 6 20, 20 4 0, 30 2 -20,
             10 0 -20, 0 0 -30 ]
}
ROUTE TS1.fraction_changed TO PI1.set_fraction
ROUTE PI1.value_changed TO T1.set_translation
DEF TS2 TimeSensor { # Small motion
  loop TRUE
  cycleInterval 5
}
DEF PI2 PositionInterpolator { # Fine movement
  key [ 0, .2, .4, .6, .8, 1 ]
  keyValue [ 0 0 0, 0 1 0, 0 2 0, 0 3 0, 0 1.8 0, 0 0 0 ]
}
DEF OI OrientationInterpolator { # More fine movement:
  # One full rotation requires at least 4 keyframes to avoid
  # indeterminate rotation:
  key [ 0, .33, .66, 1 ]
  keyValue [ 1 0 0 0, 1 0 0 2.09, 1 0 0 4.19, 1 0 0 0 ]
}
DEF V Viewpoint {
  description "Initial View"
  position 0 1.6 15
}
ROUTE TS2.fraction_changed TO PI2.set_fraction
ROUTE TS2.fraction_changed TO OI.set_fraction
ROUTE PI2.value_changed TO T2.set_translation
ROUTE OI.value_changed TO T2.set_rotation
# Only perform fine motion when cylinder is visible:
ROUTE VS.isActive TO TS2.set_enabled