Guided tours

Controlling navigation using tours

A guided tour is both an effective way of introducing a user to a virtual environment and a useful navigation device for virtual worlds where free navigation between key areas is not important or is undesirable.

The simplest form of guided tour can be made by simply creating a set of viewpoints that the user can go to in order, with appropriate viewpoint names. Most VRML browsers provide previous and next buttons that enable users to move quickly between viewpoints.

IFE's Fredriksten Festning is a good example of the use of simple viewpoints to construct a tour of an environment.

Stricter tours can be created by setting NavigationInfo to mode NONE, so that the user can interact with objects in the world, but can only navigate by going to viewpoints.

You can also take the user on a tour by simply animating the user's viewpoint. A (sort of...) example of this is IFE's Swingcoaster.

a more advanced approach is to use scripts and the node binding mechanism to move the user to different positions when the user performs an action. This approach can be used to take the user to a new location is he/she enters a special area (a 'portal') detected by a proximity sensor, or clicks on a signpost, for example.

Implementing tours using scripts can be done in a number of ways. One approach is to have a set of viewpoints that the script can bind to using one eventOut per viewpoint. Another (more common) approach is to use a script to either move a single viewpoint (in a transform group) or update a single viewpoints position and orientation fields directly.

Examples

Here is a scripted viewpoint example that uses a script node to update the viewpoints location (and a descriptive string to indicate which position index has been reached:

#VRML V2.0 utf8

NavigationInfo {
    type "NONE"
}

DEF TheView Viewpoint {
	description "Mystery tour"
	position 0 0 5
	orientation 0 1 0 0
}

Group {
	children [
Transform {
	translation  0 0 0.02
	children [
		Shape {
			geometry DEF TheDescription Text {
				string	"-"
				fontStyle FontStyle {
					justify	"MIDDLE"
				}
			}
			appearance Appearance {
				material Material {
					diffuseColor 1 1 1
				}
			}
		}
	]
}

Transform {
	translation  0 0 0
	children [
		Shape {
			geometry Box {
				size 1 1 0.01
			}
			appearance Appearance {
				material Material {
					diffuseColor 0 0 1
				}
			}
		}
	]
}

DEF TourSensor TouchSensor {}
]
}

DEF Guide Script {

    field SFInt32 tourStep 0
    field SFInt32 numberOfSteps 2

    eventIn  SFTime touchTime

    eventOut SFVec3f position_changed
    eventOut SFRotation orientation_changed
    eventOut SFBool bind_changed
    eventOut MFString string_changed

    url "javascript:
    function touchTime(touchTime, eventTime) {
        if (tourStep == numberOfSteps)
            tourStep = 0;

        tourStep++;

        if (tourStep == 1) {
            position_changed[0] = 0;
            position_changed[1] = 0;
            position_changed[2] = 5;
            orientation_changed[0] = 0;
            orientation_changed[1] = 1;
            orientation_changed[2] = 0;
            orientation_changed[3] = 0;
            string_changed[0]='1';
        }
        else
        if (tourStep == 2) {
            position_changed[0] = 0;
            position_changed[1] = 0;
            position_changed[2] = 2;
            orientation_changed[0] = 0;
            orientation_changed[1] = 1;
            orientation_changed[2] = 0;
            orientation_changed[3] = 0;
            string_changed[0]='2';
        }
        bind_changed = true;
    }"
}

ROUTE TourSensor.touchTime TO Guide.touchTime
ROUTE Guide.position_changed TO TheView.set_position
ROUTE Guide.orientation_changed TO TheView.set_orientation
ROUTE Guide.string_changed TO TheDescription.set_string
ROUTE Guide.bind_changed TO TheView.set_bind

You can animate the movement between the user's current position and the desired location by using a ProximitySensor to feed the script with the user's position and using it to set interpolator values and start a timer to move the viewpoint. See Leonard Daley's Viewpoint Animation example. Building a complete tour in this manner can be quite a lot of work.

Another example of animated tour functionality can be found in the educational Halden Reactor model on IFE's site. Note that the NONE mode has been used to restrict user navigation.

Clearly, this kind of scripting can quickly become quite complex, especially if you decide to bind/unbind NavigationInfo nodes too (for example to switch between navigation modes depending on whether the user is on a tour or not).




Michael Louka, October 10, 2001