# Simple Camera Motion

## Key Frames

The first step in creating an animation sequence is the definition of ``key-frames.'' These are descriptions of what the scene should look like at ``key'' moments in the animation sequence. Some key-frames are readily recognized. The frame in which the camera or an object starts or stops moving is important. Likewise, the moment when an object changes direction or velocity is also important. It is good to define one or two key-frames before and after each of these points of change.

Generating key-frames with mged is easy. The user displays the wireframe of the desired geometry and manipulates the display until the desired view is achieved. To save the key-frame information in a file, the mged keyboard command ``saveview'' is used. This command creates a shell script with the proper invocation of the rt program to render the current scene. The argument to the ``saveview'' command is the filename for the shell script. Note that the keyboard command ``saveview'' is distinct and different from the menu option visible in the button menu on the geometry display.

To keep things orderly and make later processing easier, it is recommended that the user specify key-frame filenames which have a common prefix followed by a number indicating the time in the animation sequence at which the key-frame occurs.

## Generating Key Frames with MGED

For our first example, we will create a simple animation with the ``moss.g'' model. The objective is to begin the animation sequence with a view of the geometry from the front corner of the platform. As time goes by, the viewer's location (the ``eye point'' or ``eye_pt'') moves upward in an arc over the geometry until the viewer is looking directly down on the center of the platform. To give a natural feeling of flight, the eye point should accelerate and decelerate at the beginning and end of its travel respectively. This is achieved by adjusting the number of degrees of elevation the eye will raise in each second of the animation. In the first (and last) three quarters of a second of the animation, the eye raises only 2 degrees of elevation above the plane. In the following second 8 degrees of arc are covered. At the 4 second mark the eye is looking down at a 45 degree angle.

    % mged moss.g
    BRL-CAD Release 4.1   Graphics Editor (MGED)
        Tue Oct 20 14:19:59 EDT 1992, Compilation 5
        stay@vail:/n/wolf/m/dist4.1/mged

    attach (nu|tek|tek4109|ps|plot|sgi|X)[nu]? sgi
    ATTACHING sgi (SGI 4d)
    Gary Moss's "World on a Platter" (units=mm)
    mged> e all.g
    408 vectors in 1 sec
    mged> center 20 0 0
    mged> size 200
    mged> ae 45 0
    mged> saveview moss_0
    mged> ae 45 2
    mged> saveview moss_0.75
    mged> ae 45 10
    mged> saveview moss_1.75
    mged> ae 45 45
    mged> saveview moss_4
    mged> ae 45 80
    mged> saveview moss_6.25
    mged> ae 45 88
    mged> saveview moss_7.25
    mged> ae 45 90
    mged> saveview moss_8
    mged> q
    %

At this stage there are seven key-frame files in the current directory with the names:

    	moss_0		moss_1.75	moss_6.25	moss_8
    	moss_0.75	moss_4		moss_7.25

A look at the contents of one of the key-frame files shows that the scene is stored as four separate elements. These elements are the geometry being displayed, the size of the viewing cube or ``viewsize'', the location in 3 dimensional space of the camera or ``eye_pt'', and the ``orientation'' of the geometry within space. All animations which involve the observer moving about a static object can be generated from these parameters.

Recall that these key-frames do not represent all of the images necessary to produce the animation. They only specify the significant moments in the animation. It is necessary to generate the ``in-between'' frames as well to turn the key-frames into a smooth animation. The values for the ``viewsize,'' ``eye_pt'' and ``orientation'' attributes of these ``in-between'' frames are generated by interpolating the values which describe the key-frames.

## Key Frame Interpolation

BRL-CAD has a utility for performing interpolation called tabinterp. It operates on files containing columns of numbers. The left-most column is always used to hold the time in the animation at which the data in the other columns occurs. A column is referred to as a ``channel.'' Lines beginning with a ``#'' character are considered to be comments, and are ignored by tabinterp. Table A shows an example input file for tabinterp.

    		Table A
    	#Time	X	Y	Z
    	0	100	0	0
    	1	 74.24	51.98	42.23
    	2	-91.85	91.85	75

This table has four channels (columns). The leftmost channel is always the ``time channel''. In this instance the ``time channel'' has the values 0, 1, and 2. The time channel has no inherent unit associated with it. These values could represent microseconds, seconds, minutes, etc. depending upon the motion being specified. The second column contains the first actual data channel in this file. In this instance it is an X coordinate. There are three data channels in this file. The contents of the file are said to form an interpolation table.

To create the ``in-between'' frames of our animation, we need to extract the values which are arguments to the ``viewsize'', ``eye_pt'', and ``orientation'' commands to rt stored in the key-frame files. These values must be tabulated for input to tabinterp.

While it would be possible to concatenate the key-frame files and edit the result by hand to create the table, this would be tedious for all but the simplest animations. Instead it is recommended that a shell script such as the ``key-chans'' shown below be employed to do the work.

        #!/bin/sh
        if [ "$#" != "1" ] ; then
        	echo "Usage: $0 basename"
        	exit
        fi
        awk '/^viewsize/ { print FILENAME " " $2}'  $1* | \
            sed -e 's/;//' -e "s/^$1//" | sort -n > chans.vsize

        awk '/^eye_pt/ { print FILENAME " "  $2  " " $3 " " $4}' $1* | \
            sed -e 's/;//' -e "s/^$1//" | sort -n > chans.eyept

        awk '/^orient/ { print FILENAME " " $2 " " $3 " " $4 " " $5}' $1* | \
            sed -e 's/;//' -e "s/^$1//" | sort -n > chans.orient

This shell script creates the three files ``chans.vsize'', ``chans.eyept'', and ``chans.orient'' from key-frame files which share the same basename (such as ``moss_''). The shared basename is specified on the command line.

    % key-chans moss_

The files ``chans.vsize,'' ``chans.eyept,'' ``chans.orient'' now contain the values needed for interpolation. The file ``chans.vsize'' contains the argument to the ``viewsize'' directive in the key-frame files. Likewise, ``chans.eyept'' contains the X, Y, and Z arguments to the ``eye_pt'' directive and ``chans.orient'' contains the quaternion argument to the ``orientation'' directive.

Now the key-frame data can be interpolated. The tabinterp program reads commands from standard input until end-of-file is found. Commands specify files from which interpolation tables should be read, which channels in the tables should be used, what type of interpolation should be applied, and the range of time over which values are needed. When end of file is reached, tabinterp performs any interpolations requested and writes out the requested results.

    % tabinterp << EOF > chans.all
    file chans.vsize 0;
    file chans.eyept 1 2 3;
    file chans.orient 4 5 6 7;
    times 0 8 3;
    interp spline 0 1 2 3 4 5 6 7;
    EOF
    cmd: file chans.vsize 0
    chan 0:  File 'chans.vsize', Column 1
    cmd: file chans.eyept 1 2 3
    chan 1:  File 'chans.eyept', Column 1
    chan 2:  File 'chans.eyept', Column 2
    chan 3:  File 'chans.eyept', Column 3
    cmd: file chans.orient 4 5 6 7
    chan 4:  File 'chans.orient', Column 1
    chan 5:  File 'chans.orient', Column 2
    chan 6:  File 'chans.orient', Column 3
    chan 7:  File 'chans.orient', Column 4
    cmd: times 0 8 3
    cmd: interp spline 0 1 2 3 4 5 6 7
    performing interpolations
    writing output
    %

In this instance, the data from the ``viewsize'' interpolation table is read into channel 0 of tabinterp. The eye point data is acquired from another file to fill channels 1, 2, and 3. The orientation table data are read into channels 4, 5, 6, and 7. The user command ``times 0 8 3'' indicates that interpolation is to be performed for the time sequence starting at time 0, through time 8 with 3 frames per time step. If each time step represents a second, this is not enough frames per second for a finished product such as a videotape, but it will be sufficient to create a preview of the sequence. It would not be wise to expend the CPU time required to compute all of the frames before we are certain that we have the sequence correct.

The last command to tabinterp selects a spline interpolation for channels 0 through 7. When tabinterp runs out of commands to process it performs the interpolation. The file ``chans.all'' contains the result of the interpolation.

Each column in chans.all represents one channel from the tabinterp session. The leftmost column is always the time channel. The column next to that is data channel 0 from the tabinterp session. An examination of the time channel on the left will reveal that the sequence runs from time 0 through time 8 and that there are 3 lines (frames) for every integer time step.

This example used only spline interpolation. There are other interpolation techniques available including step, linear, and circular spline (cspline). With step interpolation, a channel value is simply copied to intermediate time points until a new value is encountered. The circular spline technique makes certain that the starting and stopping conditions of the time sequence are identical. The second derivative of the curve at the endpoints are made to be the same. This is useful when a seamless loop of values is desired.

## Building the RT Animation Script

The program tabsub uses the output from a run of tabinterp along with a template file to write an animation script for rt. There are many types of ``macros'' which tabsub recognizes in the template. An understanding of two of these is necessary for the current example. The character ``@'' followed by an integer (such as @2) is replaced by data from the interpolation channel of that number. Note that ``@0'' refers to values from the first data channel from the interpolation. It does not refer to the time channel. The macro ``@(line)'' is replaced with the line number of the file from which the data was read. The @(line) macro serves primarily to indicate the animation frame number. A template file (``moss.proto'' for this example) should be created:

    %  cat moss.proto
    viewsize @0;
    eye_pt @1 @2 @3;
    orientation @4 @5 @6 @7;
    start @(line);
    end;

This file can be used in conjunction with tabsub to create an animation script for rt.

    % tabsub moss.proto chans.all > moss.rtanim

The resultant file ``moss.rtanim'' is rather long, so for illustration purposes only the commands for the first two frames are shown here.

    % head -n 12 moss.rtanim
    viewsize 200;
    eye_pt 90.7107 70.7107 0;
    orientation 0.270598 0.653281 0.653281 0.270598;
    start 0;
    end;

    viewsize 200;
    eye_pt 90.6992 70.6992 1.11757;
    orientation 0.26908 0.649617 0.656908 0.2721;
    start 1;
    end;

## Previewing Animations with MGED

Under a future version of BRL-CAD and beyond, the user will have the ability to preview animations using mged. Users running a 4.[012] release should skip this section. This is a useful check to run before expending the CPU time to compute the images with rt.

    %  mged moss.g
    BRL-CAD Release    Graphics Editor (MGED)
        Wed Nov 11 00:36:43 EST 1992, Compilation 770
        mike@wolf.arl.mil:/m/cad/.mged.5d

    attach (nu|tek|tek4109|ps|plot|sgi)[nu]? sgi
    ATTACHING nu (Null Display)
    Gary Moss's ``World on a Platter'' (units=mm)
    mged>  preview moss.rtanim
    tree
    eyepoint at (0,0,1) viewspace
    db_lookup:  could not find 'EYE_PATH*'
    mged>  e all.g

Don't let the ``db_lookup'' message frighten you. This is just mged telling you that there wasn't an EYE_PATH overlay prior to your first ``preview'' command. This is the name of the ``pseudo-object'' that mged creates for storing the overlay. This object is not written into the geometry database. The preview command paints a small ``L'' shape at the eye point for each frame and connects all the corners together. The location of the ``L'' indicates the location of the eye for the frame. The orientation of the ``L'' is in the plane perpendicular to the viewing direction for the frame.

Look carefully at the path the eye will take during the animation. In this instance we want the path to form an arc from near one of the corners of the platform to a point directly over the top of the platform. Does it look like what was intended? Does the arc seem to pass through any of the objects? On a machine which supports fast polygon rendering, such as the Silicon Graphics Iris, displaying the geometry with the ``ev'' command instead of the ``e'' command will make finding eye/geometry collisions much easier.

## Creating Postage Stamp Animations

Once you are convinced that the eye path is correct you are ready to produce a test animation. The file ``moss.rtanim'' can be fed directly to rt either from the command line or in a shell script. The invocation of moss.rt shown below will generate images that are 200 pixels square. This is a good size to use for an initial rendering. It will let us preview our animation before committing the resources to generate the complete animation.

    % cat moss.rt
    #!/bin/sh
    rt -M $* -o moss.pix moss.g 'all.g' 2>> moss.log < moss.rtanim

    % moss.rt -s 200

Once the frames have been computed, they can be turned into a ``postage stamp animation''. The ``pixtile'' program takes many small images and creates a bigger image from a mosaic of the small images. This image can then be displayed on a framebuffer, and the animation sequence played using the ``fbanim'' command.

    % mv moss.pix moss.pix.0
    % fbserv -S 1024 0 /dev/sgip &
    % setenv FB_FILE :0
    % pixtile -s 200 -S 1024 moss.pix | pix-fb -h
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
    % fbanim -S1024 -s200 -p5 200 25 3

The fbanim program will show the animation sequence 5 times (the ``-p5'' option specifies number of passes through the sequence). When fbanim finishes it will leave the framebuffer zoomed in on the last image. To un-zoom the framebuffer run the ``fbzoom'' program and give it the ``r'' command. This tells fbzoom to reset the framebuffer to normal. Typing ``q'' will cause fbzoom to exit.

#### Next Section
Index