If you are reading this text, apparently your HTML browser does not understand the embed element. If you know you have a VRML viewer, try opening the file: Behave.wrl

Adding Simple Behaviors to CiteMap Objects

CiteMap Builder isn't designed for general authoring of VRML97 worlds. This is good news for three reasons:

  1. CMB is very easy to use without a long learning curve
  2. CMB doesn't cost a lot of money
  3. CMB is really good at what it does: organizing linked information
But, it's bad for one main reason: there are an infinite number of cool and interesting things that can be done with VRML97 (and this doesn't always require infinite knowledge, money, or time!)

This example shows how to add simple behavior to a CiteMap scene by editing the VRML file directly. This can be tedious, but it's usually pretty fun. To be more specific, it is fun when it works at all and really fun when it works like you want it to.

The following data was added to the file Behave.wrl, which was created with the CiteMap Builder. Although it could go just about anywhere, putting it at the end of the file is usually best.
###This section adds some stuff to add simple behaviors to the Tricons

#To make the rocket rise (Tricon0)
    DEF RISE PositionInterpolator {
      key [ 0, .2, .4, .98, 1 ]
      keyValue [ 0 0 0,
                 0 1 0,
                 0 4 0,
                 0 4 0,
                 0 0 0 ]
    }
    DEF RISECLOCK TimeSensor {
      cycleInterval 5   #this is how many seconds the animation lasts
      loop FALSE        #only do it once
    }
    ROUTE Tricon0Touch.touchTime TO RISECLOCK.startTime
    ROUTE RISECLOCK.fraction TO RISE.fraction
    ROUTE RISE.value TO XfmTricon0.translation

#To make the cow flip (Tricon1)
    DEF FLIP OrientationInterpolator {
      key [ 0, .25, 0.9, 1 ]
      keyValue [ 1 0 0 0,
                 1 0 0 -1.5708,
                 1 0 0 -1.5708,
                 1 0 0 0]
    }
    DEF FLIPCLOCK TimeSensor {
      cycleInterval 4   #this is how many seconds the animation lasts
      loop FALSE        #only do it once
    }
    ROUTE Tricon1Touch.touchTime TO FLIPCLOCK.startTime
    ROUTE FLIPCLOCK.fraction TO FLIP.fraction
    ROUTE FLIP.value TO XfmTricon1.rotation

#To make the kids spin (Tricon2)
    DEF SPIN OrientationInterpolator {
      key [ 0, .5, 1 ]
      keyValue [ 0 1 0 0,
                 0 1 0 3.1416,
                 0 1 0 6.2832]
    }
    DEF SPINCLOCK TimeSensor {
      cycleInterval 2   #this is how many seconds the animation lasts
      loop FALSE        #only do it once
    }
    ROUTE Tricon2Touch.touchTime TO SPINCLOCK.startTime
    ROUTE SPINCLOCK.fraction TO SPIN.fraction
    ROUTE SPIN.value TO XfmTricon2.rotation

#To make the car drive (Tricon3)
    DEF DRIVE PositionInterpolator {
      key [ 0, .5, .6, 1 ]
      keyValue [  0 0 0,
                  0 0 3,
                  0 0 3,
                  0 0 0 ]
    }
    DEF DRIVECLOCK TimeSensor {
      cycleInterval 4   #this is how many seconds the animation lasts
      loop FALSE        #only do it once
    }
    ROUTE Tricon3Touch.touchTime TO DRIVECLOCK.startTime
    ROUTE DRIVECLOCK.fraction TO DRIVE.fraction
    ROUTE DRIVE.value TO XfmTricon3.translation
For each of four Tricons (0-3), three things were added:
  1. An interpolator
  2. A clock
  3. Some ROUTEs to connect the various pieces
We also had to add a little bit of stuff up by the Tricons themselves, but we'll summarize that a little later.

The clock is a simple timer, which will start when a Tricon is clicked (in this case) and end after a set amount of time (cycleInterval).

The interpolators come in two varieties. A PositionInterpolator works with x,y,z translation values. An OrientationInterpolator works with rotations defined by the x,y,z coordinates of a vector and a rotation angle. The key ranges from 0 to 1. When wired to a clock that lasts T secs, the interpolator key is 0 at t=0 and 1.0 at t=T. In between, the fractional change in the clock time is wired to create a fractional change in the interpolator keyValue.

The final piece is to send the results to the appropriate translation or rotation, up in the Tricon layout section (more in a moment).

For these simple behaviors, then, here is the sequence of events:

  1. Tricon clicked
  2. Clock starts
  3. Clock makes interpolator change
  4. Values from interpolator make Tricon move

There is one more set of changes that are necessary, and these are a little trickier, because they require editing lines in between existing lines. First, look for the line:

#BEGINNING of TRICON LAYOUT
All of the changes will be between this and the line:
#END of TRICON LAYOUT

Then we find the Tricon we want to animate. For example, here is the code for Tricon0:

 DEF XfmTricon0 Transform { children [ # added for behavior
        DEF Tricon0 RocketShip{
          DifCol 0.8 0.8 0.9
          SpecCol 1 1 0.5
          Shiny 0.2
        }
 ]}# added for behavior
The two lines that say "# added for behavior" were not there when CMB wrote the file: we added them for the behaviors. The hardest part is putting the lines in the right spot. (In fact, for some animation effects, the transforms must be nested and/or placed differently).

OK. Well, that isn't so bad. It gets better after you stare at things for awhile. But, there's one more ripple. To flip the cow correctly, we really want the cow to rotate about an axis near the floor. To do this, we can define a "center" to the added transform, viz:

 DEF XfmTricon1 Transform { center 0 -0.45 0 children [ # added for behavior
This makes the cow rotate about an axis near the floor.

This is a quick example to show what is possible. Working with clocks, interpolators, routes, and transforms is not always easy, but hopefully the example will provide enough to get started.

Bonus tip: if you want to make an object animate all the time, simply set the clock parameters to something like this:

    DEF SPINCLOCK TimeSensor {
      cycleInterval 2   #seconds in each cycle
      loop TRUE         #do it forever
    }
and remove the ROUTEs for that Tricon. Keep the number of continually running animations small (one or two is best) --- if too many things are animating, it can slow the browser down (not to mention irritate the user).

Here is the CiteMap Builder CMB file for this example: Behave.cmb (right click to download).

The VRML file for this example was left uncompressed so that it could be easily viewed. Load and View Source in the browser, or save the file by right clicking: Behave.wrl


Return to CiteMap Builder Examples.