Example: Bus

We want to design a 3d world in which there is a bus that can drive along a route. The intended route starts from Center station, then go to Theater, City call, Museum, and Zoo, and then be back to Center Station again. The locations are shown in the map.

At the beginning, the bus stops at the Center station. We use a Timesener to set the bus driving time. We set the period of the bus goes through the whole route as two minutes, namely, 120 seconds, which can be done as follows. We want the bus stopping the driving after the route, therefore, we set the loop FALSE.

DEF BusTimer TimeSensor { cycleInterval 120 loop FALSE}

Moreover, we need a proximity Sensor to trigger the timesensor, so that whenever the user enters the bus, the bus starts driving. Since the bus stops at the center station, and the position of Center station is <0,0,0>. Therefore, the proximity sensor can de defined as follows:

DEF BusSensor ProximitySensor {center 0 1.5 0 size 8 3 3}

In order to make the bus driving along the intended route, we have to set the bus' position and the bus' rotation according to the corresponding driving time. We divide the total time period as 100 fractions. We decide that the bus goes to North at the fraction 0.12, leaves from Theater at the fraction 0.19, leaves from City Hall at the fraction 0.43, leaves from Museum at the fraction 0.52, leaves from Zoo at 0.78, and go to west at the fraction 0.84, and arrives at the Center Station at 1.0.

Therefore, the bus' position and rotation can be implemented by the following position interpolator and orientation interpolator:

DEF BusPosition PositionInterpolator
{key [ 0, 0.01, 0.02, .03, .04, .05, .06, .07, .08, .09,
.10, .11, .12, .13, .14, .15, .16, .17, .18, .19,
.20, .21, .22, .23, .24, .25, .26, .27, .28, .29,
.30, .31, .32, .33, .34, .35, .36, .37, .38, .39,
.40, .41, .42, .43, .44, .45, .46, .47, .48, .49,
.50, .51, .52, .53, .54, .55, .56, .57, .58, .59,
.60, .61, .62, .63, .64, .65, .66, .67, .68, .69,
.70, .71, .72, .73, .74, .75, .76, .77, .78, .79,
.80, .81, .82, .83, .84, .85, .86, .87, .88, .89,
.90, .91, .92, .93, .94, .95, .96, .97, .98, .99, 1.0]

keyValue [ 0 0 -1.5, 8 0 -1.5, 16 0 -1.5, 25 0 -1.5, 32 0 -1.5,
40 0 -1.5, 48 0 -1.5, 56 0 -1.5, 64 0 -1.5, 72 0 -1.5, #.9
80 0 -1.5, 88 0 -1.5, 98.5 0 -1.5, 98.5 0 -9.5, 98.5 0 -17.5, #.12 go to north
98.5 0 -25.5, 98.5 0 -33.5, 98.5 0 -41.5, 98.5 0 -45.5, 96 0 -48.5,#.19
96 0 -48.5, 96 0 -48.5, 88 0 -48.5, 78 0 -48.5, 68 0 -48.5, #go to west
58 0 -48.5, 48 0 -48.5, 38 0 -48.5, 28 0 -48.5, 18 0 -48.4,#.29
8 0 -48.5, -8 0 -48.5, -18 0 -48.5, -28 0 -48.5, -38 0 -48.5, #
-48 0 -48.5, -58 0 -48.5, -68 0 -48.5, -78 0 -48.5, -88 0 -48.5,#.39
-96 0 -48.5, -96 0 -48.5, -96 0 -48.5, -98.5 0 -40, -98.5 0 -30, #.43 goto south
-98.5 0 -20, -98.5 0 -10, -98.5 0 0, -98.5 0 8, -98.5 0 16, #.49
-98.5 0 24, -98.5 0 32, -98.5 0 48, -98.5 0 48, -98.5 0 48, #.52 go to east
-88 0 48.5, -80 0 48.5, -72 0 48.5, -64 0 48.5, -56 0 48.5,#.59
-48 0 48.5, -40 0 48.5, -32 0 48.5, -24 0 48.5, -16 0 48.5, #
-8 0 48.5, 6 0 48.5, 14 0 48.5, 24 0 48.5, 34 0 48.5,#.69
44 0 48.5, 54 0 48.5, 64 0 48.5, 74 0 48.5, 84 0 48.5, #
96 0 48.5, 96 0 48.5, 96 0 48.5, 98.5 0 40, 98.5 0 32,#.79, .78 go to north
98.5 0 24, 98.5 0 16, 98.5 0 8, 98.5 0 -1.5, 90 0 -1.5, #.84 go west
80 0 -1.5, 70 0 -1.5, 60 0 -1.5, 50 0 -1.5, 40 0 -1.5, #.89
30 0 -1.5, 20 0 -1.5, 10 0 -1.5, 0 0 -1.5, -8 0 -1.5, #
-8 0 -1.5, -8 0 -1.5, -8 0 -1.5, -8 0 -1.5, -8 0 -1.5, -5 0 -1.5 #1.0
]}

DEF BusRotation OrientationInterpolator

{key [
0, .01, .02, .03, .04, .05, .06, .07, .08, .09,
.10,.11,.12, .13, .14, .15, .16, .17, .18, .19,
.20,.21,.22, .23, .24, .25, .26, .27, .28, .29,
.30, .31, .32, .33, .34, .35, .36, .37, .38, .39,
.40, .41, .42, .43, .44, .45, .46, .46, .47, .48, .49,
.50, .51, .52, .53, .54, .55,.56, .57, .58, .59,
.60, .61, .62, .63, .64, .65, .66, .67, .68, .69,
.70,.71,.72,.73, .74,.75,.76,.77,.78,.79,
.80,.81,.82,.83, .84, .85, .86,.87,.88,.89,
.90,.91,.92,.93,.94, .95, .96, .97, .98, .99, 1.0, 1.01]

keyValue [
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0,
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, #.09
0 1 0 0, 0 1 0 0, 0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 1.5708,
0 1 0 1.5708,0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 3.1416, #.19
0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,
0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,#.29
0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,
0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,#.39
0 1 0 3.1416,0 1 0 3.1416,0 1 0 3.1416,0 1 0 -1.5708,0 1 0 -1.5708,
0 1 0 -1.5708,0 1 0 -1.5708, 0 1 0 -1.5708, 0 1 0 -1.5708, 0 1 0 -1.5708,#.49
0 1 0 -1.5708,0 1 0 -1.5708, 0 1 0 0, 0 1 0 0, 0 1 0 0,
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, #.59
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0,
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0,#.69
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 0,
0 1 0 0, 0 1 0 0, 0 1 0 0, 0 1 0 1.5708, 0 1 0 1.5708, #.79
0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 1.5708, 0 1 0 3.1416,
0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416, #.89
0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416, 0 1 0 3.1416,
0 1 0 2.4, 0 1 0 1.5708, 0 1 0 1, 0 1 0 .5, 0 1 0 0, 0 1 0 0, 0 1 0 0 # bus turns around
]}

The ROUTES for the binding above can be done by the followings:

ROUTE BusSensor.enterTime TO BusTimer.startTime
ROUTE BusTimer.fraction_changed TO BusPosition.set_fraction
ROUTE BusTimer.fraction_changed TO BusRotation.set_fraction
ROUTE BusPosition.value_changed TO bus1.set_position
ROUTE BusRotation.value_changed TO bus1.set_rotation

We want the user goes with the bus. It can be done by setting the user viewpoint's position and orientation as the same values of bus' position and rotation, namely, which can be done as follows:

ROUTE BusPosition.value_changed TO viewpoint.set_position
ROUTE BusRotation.value_changed TO viewpoint.set_orientation

Note that the bus' Y-position is always 0, which is too low for the user' viewpoint. In order to use the same key values, we can simply define a new viewpoint, then move the viewpoint's position to a little higher one, like <0, 1.5, 0>, which can de done like this:

PROTO viewpoint [ exposedField SFVec3f position 0 0 0
exposedField SFRotation orientation 0 0 1 0]
{ Transform {translation 0 1.5 0
children Viewpoint { position IS position
orientation IS orientation } } }

The demo of the bus example is available here.