Keyframe Animator - animate geometry objects using frame interpolation

Name

	Keyframe Animator - animate geometry objects using frame interpolation

Summary

	Name	Keyframe Animator (V3.00)
	Type	mapper
	Inputs	integer (optional) -- animate pulse in
		struct upstream_transform (invisible) -- mouse information in
		struct upstream_geom (invisible) -- pick information in
	Outpts	geom -- object transformations
		integer (invisible) -- animate pulse out
	Parms	Name		Type		Description
		exit		oneshot		exit the Keyframe Animator module
		>>>		string		value of current attribute
		obj attributes	choice		object attribute selector
		new obj		oneshot		add a new object to the list
		del obj		oneshot		delete current object from list
		add obj		boolean		add an object by picking
		next obj	oneshot		animate next object in the list
		ROTATE		boolean		rotation interpolation is active
		TRANS		boolean		translation interpolation is active
		SCALE		boolean		scale interpolation is active
		ACTIVATE ALL	oneshot		turn on all interpolation buttons
		DEACTIVATE ALL	oneshot		turn off all interpolation buttons
		init transforms	oneshot		reset active transforms to defaults
		update frame	boolean		current frame update on/off
		animation frame	islider		changes the current frame
		<--		oneshot		move back a frame
		-->		oneshot		move forward a frame
		prev key	oneshot		jump backward to prev keyframe
		next key	oneshot		jump forward to next keyframe
		animate		boolean		runs the current animation 
		anim mode	choice		change the animation mode
		anim speed	islider		sets skip value for playback
		anim start	integer		sets the start of anim window
		anim end	integer		sets the end of anim window
		save keyframe	oneshot		saves position as keyframe
		ease in		boolean		create interpolation ease-in
		ease out	boolean		create interpolation ease-out
		create interp	oneshot		interpolates animation window
		create sp intrp	oneshot		spline interpolates window
		create hold	oneshot		copies a frame to entire window
		trace obj path	boolean		traces translations in window
		clear keyframe	oneshot		unmark a frame as keyframe
		clear all keys	oneshot		unmark all frames as keyframes
		clear frme info	oneshot		clear keys & info from anim window
		wait for sync	boolean		wait for a specified anim pulse
		sync frme	integer		the sync pulse to wait for
		load anim	boolean		show/hide load anim popup
		save anim	boolean		show/hide save anim popup
		edit settings	boolean		show/hide settings popup
		load animation	file browser	load animation file browser
		load animation	file browser	save animation file browser
		cancel load	oneshot		hide load anim browser
		cancel save	oneshot		hide save anim browser
		key type	choice		type of key markers for trace
		key size	islider		size of the key markers
		close settings	oneshot		hide the settings popup

Description

	The Keyframe Animator module is used to animate objects which
	are displayed through the Geometry Viewer subsystem.  It works
	by supplying a transformation matrix to the Geometry Viewer
	module for any object which has been loaded into the Geometry
	Viewer or supplied to the Geometry Viewer module's geom input
	by other modules.  Generally, the Keyframe Animator's geometry
	output (the transformation matrix) is supplied to the geometry
	input of Geometry Viewer.
	
	Adding Objects:
	The name of the object to be animated is typed into the ">>>"
	input.  The Keyframe Animator will only allow you to enter
	object names that exist in the current view.  To get a list of
	objects in the current view, go into the Geometry Viewer (under
	the Data Viewer's pulldown menu of the Network Editor), and
	click on the small square in the current object selector (the
	bar above the small object window).  To see the list of objects
	for a different view, click in that view's window.  These
	object names should be preceded by a percent symbol (%) in the
	Keyframe Animator (if you type them without the percent symbol,
	one will be added automatically).  Cameras and lights cannot be
	animated.  Use the "%top" object to animate all of the objects
	in the window.
	Using the Mouse:
	Instead of typing in the name of the object, you can use the
	mouse to pick the object you want to animate.  To add the
	object, click the "add obj" button and use the left mouse
	button to click on the object in the display window.  You will
	then be asked if you want to add the object, replace the
	current object, or abort.  Press "REPLACE OBJ" to animate the
	new object.  See below for more details on the other options.
	Clicking in the background of the display window with the left
	mouse button will allow you to animate the "%top" object.
	Controlling the Object:
	The object can then be rotated, translated, and sized
	interactively using various input devices supported by AVS
	(mouse, dialbox, and/or spaceball).  With the mouse, use the
	middle and right mouse buttons to transform the object.  The
	middle mouse button rotates the object and the right mouse
	button translates the object.  Holding either SHIFT key while
	pressing the right mouse button will translate the object in
	the Z direction.  Holding the SHIFT key while pressing the
	middle mouse button will size the object.  The "initialize
	transformations" button will reset the transformations to their
	default values.
	Keyframe Animation Interpolation:
	Keyframe animation is done by saving an object in certain key
	positions called "keyframes" and allowing the Keyframe Animator
	to interpolate the in-between frames.  This is done by moving
	the object to the desired key position, orientation, and size,
	moving the "animation frame" slider to the frame at which you
	want that object at that position, and pressing the "save
	keyframe" button.  Then, choose another keyframe position in
	the same manner, by moving the object to the chosen position,
	moving the animation frame to the desired frame, and pressing
	the "save keyframe" button.  Any number of keyframes can be set
	at various frames.  Pressing the "create linear interpolation"
	button will fill in the empty frames based on straight lines
	between the keyframe positions, thus creating an animation.
	Pressing "create spline interpolation" will instead fill in the
	empty frames based on a smooth curve which goes through all
	keyframes.  The "ease in" and "ease out" buttons are used to
	make an object gradually speed up and slow down near the
	beginning or end of it's path.  If "ease in" is lit when doing
	a linear or spline interpolation, the object will gradually
	speed up between the first and second keyframes of the
	animation window.  Similarly, if "ease out" is lit, the object
	will slow down between the next to last and last keyframes of
	the animation window.  The "create hold" button will copy the
	object's currently saved position (the position which has been
	saved for the object at the current frame) to all the other
	frames in the animation window.  This is used for objects which
	remain in one place during the animation.  Note that "create
	hold" copies the current position to all other frames,
	including keyframes, so previously stored frame information
	will be overwritten!  Use this button with caution.
	The "Update Frame" Button:
	When a keyframe is set using the "save keyframe" button, or
	when in-between frames are calculated using "create linear
	interpolation", "create spline interpolation", or "create hold"
	the object's position, orientation, and size are stored into
	memory at each frame.  When an object is moved with the mouse,
	spaceball, or dialbox it is no longer in its stored position
	until the new position is stored.  When the "update frame"
	button is lit, the object will always move to the previously
	stored position at the current frame.  To see the saved
	position of an object at any frame, move the "animation frame"
	slider to the desired frame and make sure that the "update
	frame" button is lit.  The "update frame" button automatically
	lights up during certain operations such as "create linear
	interpolation", "create spline interpolation", and "create
	hold" and automatically unlights when an object is moved, so
	that you will see the object move rather than stay at the
	stored position.
	Moving Around Your Animation:
	The "-->" and "<--" buttons can be used to step through frames
	of the animation by increasing or decreasing the current
	animation frame number.  The "prev key" and "next key" buttons
	can be used to jump to the previous or next keyframe.  The
	"animation speed" slider can be used to make the arrow buttons
	increase (or decrease) by more than one frame.  Negative values
	will cause the animation to run backwards (it will in effect
	switch the meanings of the two arrow buttons).  The "animate"
	button will cause the animation to run as if you pressed the
	arrow buttons repeatedly.  The "once," "loop," "swing," and
	"off" buttons affect the behavior of the animation when the
	current frame goes beyond the "anim end" or "anim start"
	values.  The "loop" button causes the current frame to "wrap
	around" when it goes beyond the "anim end" value so that the
	current frame will be the "anim start" value.  Similarly, the
	frames will wrap around the other direction if you are stepping
	through the animation backwards.  The "once" button causes the
	current frame to remain on the last frame as you step forward
	past the end of the animation window, or to remain on the first
	frame as you step backwards past the start of the animation
	window.  The "swing button" causes the "animation speed" slider
	to reverse directions when you step past the end of the
	window.  The "off" button is exactly the same as the "once"
	button except that it turns off the "animate" button when the
	current frame gets to the end of the animation window (or the
	beginning if it's running backwards).
	The "Trace Object Path" Button:
	After interpolating, turning on the "trace object path" button
	will display the path that the current object will take through
	the animation.  The keyframes are also displayed along the path
	as frame numbers.  Turning the button off will remove the path
	trace from the screen.  Note that tracing the path of the
	"%top" object has strange results.
	Clearing Keyframes and Frame Information:
	It may be desirable to unmark certain frames so that they are
	no longer thought of as keyframes for interpolation.  Use the
	"clear keyframe" button to mark the current frame as not being
	a keyframe, and use the "clear all keyframes" to clear all
	keyframes.  The "clear keys and frame information" button is
	used to wipe out all of the saved transformations in the
	animation (set them to their default values), including the
	keyframes, and remove all keyframes.  Use the "clear keys and
	frame information" button with caution!
	Loading and Saving Your Animation:
	To save an animation, press the "save anim" button to bring up
	a filename browser.  Press "New File" to save the file under a
	new name or to type in the name of the file to replace, or
	select a filename to replace from the browser.  Pressing
	"cancel save" or turning off the "save anim" button will close
	the file browser window.  If the file already exists, you will
	be asked if you wish to replace it.  To load the animation back
	in, press the "load anim" button to bring up a filename
	browser.  Press "New File" to type in the filename to load or
	select a filename from the browser.  You will be given several
	choices at this point.  You can replace whatever animation
	might currently be in memory by pressing the "LOAD" button
	(this is usually what you will want to do).  The "MERGE" and
	"APPEND" buttons are discussed in the ADVANCED TOPICS below.
	The "update frame" button will automatically light after the
	load so that you can immediately see the new animation.
	Pressing "cancel load" or turning off the "load anim" button
	will close the file browser window.  Animation filenames always
	end with ".anim" as an extension.  If you save a file without
	the extension, it will be added to the end of the filename.
	Only files with the correct extension appear in the load and
	save browsers.  The current animation file is shown in the
	title area at the top of the Keyframe Animator panel.  Note
	that previous versions of the Keyframe Animator may use
	different file formats.
	The Settings Menu:
	Clicking on "edit settings" will open a window with settings
	options.  Here you can change the way the trace object path
	appears by choosing numeric keyframe markers (the default),
	spherical keyframe markers, or turning off the keyframe
	markers.  You can also change the size of the keyframe
	markers.  Click "close settings" to close the settings window.
	Exiting the Keyframe Animator:
	In order to exit the Keyframe Animator properly, it is best to
	use the "exit" button.  You will be asked if you really want to
	exit, at which time pressing "OK" will turn off the trace
	object (if it is on), close any popup windows that you may have
	left open, return all objects to their default transform and
	picking status, and exit the Keyframe Animator.  Press "Cancel"
	if you don't wish to exit.
	ADVANCED TOPICS:
	More About the "Update Frame" Button:
	The "update frame" button, when lit, forces the object to move
	to the saved position.  This can be used to move an object
	relative to a saved position by turning "update frame" on,
	moving the object relative to its current position, changing
	the "animation frame" number, and saving the new position as a
	keyframe.
	The "Animation Window":
	More frames can be added to an animation by increasing the
	"anim end" value.  The "anim end" and "anim start" inputs also
	change the frames which are selectable with the "animation
	frame" slider.  The frames within the "anim start" and "anim
	end" values comprise the current "animation window."  Certain
	operations such as "clear keys and frame information", "create
	linear interpolation", "create spline interpolation", "create
	hold", and "trace object path" will affect only the frames
	within the current animation window for the current object (see
	Handling Multiple Objects below).  The current "start frame"
	and "end frame" are automatically defined as keyframes before
	interpolation.  When you press "save anim" to save your
	animation, if the current "animation window" is smaller than
	the number of frames that have been defined for the animation,
	you will be asked if you want to save ONLY the animation
	window, or if you want to save the entire animation.
	"Active" Transformation Buttons:
	Note that when an object is transformed, it's corresponding
	"active button" ("ROTATE", "TRANS", "SCALE") is automatically
	lit depending on whether you have rotated, translated, or
	scaled the object.  The reason for this is that when you create
	an interpolation by pressing "create linear interpolation",
	"create spline interpolation, or "create hold" (and also "clear
	keys and frame information") only those transformations which
	are lit will be interpolated, making it possible to control
	exactly which transformations will be interpolated by manually
	turning on and off the "active buttons."  Furthermore, many of
	the other operations which affect the transformations will
	affect only those which are currently active.  For example,
	"initialize transformations" will only initialize those
	transformations which are active, and the "save keyframe"
	button will save only the transformation values which are
	active.
	Handling Multiple Objects:
	More than one object may be animated at a time.  Use "new obj"
	to create an "EMPTY" object.  You should then change its name
	by typing in a new name in the text area marked ">>>".  Note
	that the Keyframe Animator will automatically ignore objects
	which begin with "EMPTY" in all caps, so the Geometry Viewer
	will not complain that it doesn't know of an object called
	"EMPTY-2".  Use "del obj" to change the current object to an
	"EMPTY" object.  Use "next obj" to make another object the
	current object.  When dealing with more than one object, the
	transformations only affect the current object, and the
	positions of all non-current objects are always updated whether
	or not "update frame" is on.  After making a new object the
	current object (by either pressing "next obj" or clicking on
	the object with the left mouse button), the "update frame"
	button will automatically light to show you the saved position
	of the new object.  You may then animate that object as usual.
	When you press "save anim" to save your animation, if any of
	the objects begin with "EMPTY" you will be asked if you want to
	save ONLY objects which are NOT "empty," or if you want to save
	ALL the objects (including ones whose names begin with
	"EMPTY").  This allows you to, in effect, delete objects by
	simply naming them "EMPTY" so they won't be saved with the rest
	of the objects if you don't want them to be.  If all of the
	objects currently defined begin with "EMPTY" they will always
	be saved, and you will not be given the choice.  Most
	operations such as creating interpolations, "trace object
	path", and "clear frame information" affect only the current
	object.  Keyframes are marked globally so if you press "save
	keyframe" at frame 30 while animating one object, frame 30 will
	be thought of as a keyframe when animating all objects (until
	the keyframe is cleared).
	Picking:
	Instead of using the "new obj" and "next obj" buttons, you can
	use the mouse to make a particular object current, add a new
	object, or change the name of the current object.  To make an
	object current, simply use the left mouse button to choose the
	object in the display window.  Clicking in the background of a
	window will make the "%top" object the current object.  To
	control an object that is not currently under the control of
	the animator, or to replace the current object with an object
	not currently under control, press the "add obj" button, then
	click on the object with the left mouse button.  If the object
	doesn't currently exist as one of the objects you are
	animating, you will be asked if you want to add it or replace
	the current object.  Press "ADD OBJ" to add the object to the
	other objects you are animating.  Press "REPLACE OBJ" to change
	the name of the current object to the new object.  Press
	"ABORT" to do nothing.
	About Parenting:
	Parenting is a powerful way of creating complex moves.  An
	object will always move in relation to it's parent's
	transformations, so if object "%dodec.1" has a parent
	"%harmonic.2", moving object "%harmonic.2" will affect both
	objects while moving object "%dodec.1" will affect only
	"%dodec.1".  In other words, a "parent" will affect it's
	"children" which will in turn affect their "children" and so on
	(thus a parent will affect all of it's "offspring").  To change
	an object's parent, simply click the "parent" button, and type
	the new parent into the ">>>" input.  When you press the "trace
	object path" button, the "ANIM-Trace" object is automatically
	parented to the current object's parent, so that the trace will
	reflect the current object's true path.  Unpredictable results
	can occur if you create a "parenting loop" (by assigning an
	object's "offsprings" as a parent of that object).  Parenting
	an object to itself is not advised.  Objects that have been
	parented to other objects will remain parented to those objects
	even if you change the "name" attribute to control a different
	object.  You should probably change an object's parent back to
	"%top" before assigning a new value for the "name" attribute.
	Note that the "%top" object is always at the top of the "family
	tree," so animating the "%top" object always animates all
	objects in the scene.
	About Quaternion Rotation:
	There are two widely used methods used to interpolate
	rotational positions of objects:  matrix rotation and
	quaternion rotation.  Regular rotation uses the traditional X,
	Y, and Z transformation dials which are accumulated before
	combining them in a transformation matrix.  This has two
	unfortunate side effects.  One, using absolute rotation values
	can create a problem sometimes known as "gimbal lock," the loss
	of a degree of rotational freedom when trying to rotate an
	object to certain positions.  The other unfortunate side effect
	is that matrix interpolation chooses an unpredictable rotation
	path between two positions, since it linearly interpolates the
	X rotations, the Y rotations, and the Z rotations separately,
	then concatenates the three matrices to create the final
	rotation transformation.  Quaternion rotation solves both of
	these problems.  One, objects can be rotated intuitively (an X
	rotation always rotates around the horizontal, a Y rotation
	around the vertical, and a Z rotation perpendicular to the
	screen).  Also, quaternion interpolation chooses the shortest
	path between two positions by considering rotations as points
	on the surface of a sphere and interpolating based on a "great
	circle" on the sphere.  The only drawback to using quaternion
	rotation is that the object must be rotated less than 180
	degrees or the shortest path will then be in the opposite
	direction.  The work around to this is to save intermediate
	keyframes so that the rotations between keyframes are always
	less than 180 degrees.  Spline quaternion rotation will
	correctly fit a spline curve through the keyframe rotation
	positions on the surface of the rotational sphere.
	More on the "Load Anim" Operation:
	During a "load animation" operation, three options are
	presented aside from replacing the animation currently in
	memory.  The "MERGE" button will allow you to merge the file
	with the animation currently in memory, thus adding to the
	objects in memory rather than overwriting them.  "APPEND" will
	add the frames stored in the file to the end of the frames
	currently in memory, but will ignore the object names in the
	saved file, appending the frames for the first object in the
	file to the frames of the first object in memory, and so on.
	Use "ABORT" to abort the loading process and return to the
	Keyframe Animator.  If the file you are loading was created
	with an older version of the Keyframe Animator, a warning will
	be given when the file is loaded.  You can then abort the load,
	or attempt to load the file anyway.  There is no guarantee that
	files created by different versions of the Keyframe Animator
	will be the same format.  You can examine the file and compare
	it against the format described below in the ANIMATION FILE
	FORMAT section at the end of this documentation.
	Attaching a Driver Coroutine to the Keyframe Animator:
	The invisible "animation pulse" input allows an integer to be
	supplied by a "driver" coroutine module (such as "animated
	integer"), causing the current animation frame to be increased
	or decrease by the "animation speed" value every time the pulse
	is received.  See INPUTS and EXAMPLES below.  The "wait for
	sync" button and "sync frme" text input are only useful if the
	Keyframe Animator's "animation pulse" input is connected to a
	driver module or to a downstream record module.  The "wait for
	sync" will cause the Keyframe Animator to wait for a specific
	integer at its "animation pulse" input before it will begin
	incrementing the "animation frame".  The integer which the
	Keyframe Animator will wait for is specified with the "sync
	frme" text input.  When this integer is received, the "wait for
	sync" button will automatically unlight, the current animation
	frame will be incremented, and subsequent integers (reguardless
	of their values) will be taken as pulses and will cause the
	current animation frame to be incremented.  The "loop," "once,"
	and "swing" buttons have the same affect when driving the
	module with a coroutine driver as they have when manually
	pressing the arrow keys and when viewing the animation with the
	"animate" button (see above).  When a pulse is received through
	the "animation pulse" input, the "update frame" button will be
	turned on automatically so that the animation will be shown.
	
	Driving an Output Module:
	The invisible "animation pulse" output can be used to drive a
	downstream module with the Keyframe Animator.  This is
	especially useful for saving images to disk or to a video
	device.  The output will only be changed when the current scene
	is changed by the Keyframe Animator.  The value of the output
	is an integer corresponding to the current animation frame.

Inputs

	Animation pulse in (integer) -- invisible.
	The "animation pulse" input is an integer, usually supplied by
	a coroutine module which repeatedly sends integers in order to
	drive the Keyframe Animator.  Each time the Keyframe Animator
	receives an integer into the "animation pulse" input, the
	"update frames" button is lit and the "current frame" is
	incremented (or decremented) by the "animation speed" value
	(this is identical to manually pressing the "-->" button).  The
	"once," "loop," and "swing" buttons also affect the animation
	playback when using the "animation pulse" input.  The "animated
	integer" module supplied with AVS can be used as an animation
	driver by simply connecting its output to the "animation pulse"
	input of the Keyframe Animator, by pressing the "animated
	integer" module's "Continuous" button, and by turning its
	"sleep" button off.  Turning "sleep" on again will stop the
	animation.  (Note that the "animate" button of the Keyframe
	Animator will allow you to do the same thing without a driver
	module.)  See the EXAMPLE networks below.  When recording your
	animation to an external video device such as a Lyon-Lamb
	Minivas videotape controller or a Sony Laser Videodisc
	recorder, the "animation pulse" input can be used to
	synchronize the recording process.  Presumably, a module used
	to record an animation and control the external devices will
	take as input an image from "geometry viewer" so that it can
	tell when the image has changed, and will produce an integer
	pulse output when the frame has been recorded to videotape or
	videodisc.  This output would then be fed upstream to the
	Keyframe Animator to complete the loop, causing it to produce
	the next frame of the animation.  See the EXAMPLE networks
	below.  This input is invisible since it is often not used.
	Upstream trans in (struct upstream_transform) -- invisible.
	This is the input used to receive mouse movements from the
	Geometry Viewer in order to transform an object with the
	mouse.  This invisible input will automatically be connected to
	the "geometry viewer" invisible "upstream_transform" output
	when the "Keyframe Animator" module is connected to the
	"geometry" input, so the user does not have to connect it by
	hand.
	Upstream geom in (struct upstream_geom) -- invisible.
	This is the input used to receive pick information from the
	Geometry Viewer.  This invisible input will automatically be
	connected to the "geometry viewer" invisible "upstream_geom"
	output when the "Keyframe Animator" module is connected to the
	"geometry" input, so the user does not have to connect it by
	hand.

Outputs

	Transformation matrices (geom).
	Every time the Keyframe Animator module fires, it produces a
	transformation matrix for each object as geometry which is then
	fed to a module which accepts geometry such as the "geometry
	viewer."
	Animation pulse out (integer) -- invisible.
	This output can be used as input to other modules which might
	need to receive a pulse at each frame of an animation.  The
	integer sent is the current "animation frame" value, so it can
	also be used to let user-defined modules know what frame the
	Keyframe Animator is on.  This output is invisible since it is
	seldom used.

Examples

	Simple animation network:
	The "animated integer" module is used as the driver for the
	animation (note that this is not normally necessary since the
	"animate" button can be used to view the animation).  Objects
	are loaded in via the "Geometry Viewer" subsystem's "Read
	Object" button (the "Objects" button must be lit in the "Menu
	Selection" section before the "Read Object" button is
	visible).  Once loaded, the objects can be animated using the
	Keyframe Animator, and the animation can be played back by
	choosing "Continuous" playback and turning off "sleep" for the
	"animated integer" module:
			       animated integer
			              |
			              |
			      Keyframe Animator
			              |
			              |
			       geometry viewer
	Network to record an animation to an external device:
	The Keyframe Animator waits for the "Record Animation" module
	to send it a pulse after the current frame has been stored to
	the videotape or videodisc.  The "Record Animation" module
	waits for "geometry viewer" to complete the rendering process
	and display the image before it fires and records the frame:
	              ,---------------------------------------.
	              |                                       |
	              V                                       |
	      Keyframe Animator                               |
	              |                      (upstream pulse) |
	              |                                       |
	       geometry viewer                                |
	              |                                       |
	              `------------------.                    |
	                                 |                    |
	                          Record Animation            |
	                         (to record to tape or disc)  |
	                                 |                    |
	                                 `--------------------'
BUGS AND WORKAROUNDS
	AVS will crash if the Keyframe Animator is saved into a network
	then loaded back in.  Don't save the Keyframe Animator as part
	of a network.  Always drag the module down and connect it by
	hand.
	Because matrix calculations within AVS are done as floats
	instead of doubles, rounding errors occur causing the SCALE
	button to light sometimes when you're only rotating an object.
	Currently there is no workaround.
	Due to a bug in AVS concerning sliders in immediate mode, the
	"animation frame" slider occasionally shows a different value
	than the slider is actually producing.  Clicking one of the
	arrow buttons will update the animation so that it matches the
	slider value.
	Because certain operations aren't allowed in a module's
	destroy routine, any popup windows created by the Keyframe
	Animator that are open when you kill the module will remain
	behind.  Also, the trace object will remain behind if left on
	when the module is killed and any object under the control of
	the Keyframe Animator will retain its parents and its transform
	and notify status.  Always use the "exit" button to kill the
	Keyframe Animator module.
	Animating cameras and lights doesn't work properly (AVS doesn't
	seem to notify transformations of lights and cameras).  There is
	no workaround except to animate the "%top" object instead of the
	camera.
FUTURE ENHANCEMENTS
	Loading objects in through the Keyframe Animator instead of
	having to load them in via the Geometry Viewer subsystem.
	Picking an object's parent using the mouse instead of by typing
	in the name of the parent object.
	Support for interpolation of other object attributes like
	color, as well as interpolation of parameters from other
	modules in the network.
	
	Having separate keyframe lists for each object.

Related modules

	animated integer, geometry viewer
		see AVS documentation for more information.
	Record Animation, written by Brian Kaplan
		allows recording to Lyon-Lamb Minivas and Sony Laser
		Videodisc devices.

Author

	created by Brian Kaplan
		kaplan@cica.cica.indiana.edu
		Center for Innovative Computer Applications (CICA)
		Indiana University
	Most of the quaternion interpolation code was modified from code
	written by Andrew Hanson and Robert Cross, Department of
	Computer Science, Indiana University, with their permission.
ANIMATION FILE FORMAT
	The Keyframe Animator stores its files in a simple ASCII
	format.  The file contains a version number of the Keyframe
	Animator module that produced it (VERSION).  On the following
	line are the number of frames in the animation (NFRMS) and the
	number of objects (NO).  The following  lines consists of
	the object list, one object per line.  On each line are the
	object number (OBJ##), name of the object (%NAME), and the
	parent of the object (%PARENT).  Following the object list is
	the animation frame list.  Each of the  frames in the
	the frame list contains the frame number (FRAME#####) and
	whether or not that frame is a keyframe (KEY) on a line,
	followed by transformations for each object in the animation.
	The transformations consist of three lines each.  The first
	contains the object number (OBJ##) and scale for that object
	(SCLE).  The second line contains the quaternion rotation
	values for the object (QTRX, QTRY, QTRZ,QTRC).  The last line
	of each transformation section contains the translation values
	for the object (XTRN, YTRN, ZTRN).
	The file looks like this:
	VERSION
	NFRMS NO
	obj01: %NAME %PARENT
          :
          :
        objNO: %NAME %PARENT
	frame00001: KEY
	     obj01: SCLE
	            QTRX QTRY QTRZ QTRC
	            XTRN YTRN ZTRN
                :
                :
	     objNO: SCLE
	            QTRX QTRY QTRZ QTRC
	            XTRN YTRN ZTRN
	   :
	   :
	frameNFRMS: KEY
	     obj01: SCLE
	            QTRX QTRY QTRZ QTRC
	            XTRN YTRN ZTRN
                      :
                      :
	     objNO: SCLE
	            QTRX QTRY QTRZ QTRC
	            XTRN YTRN ZTRN
	
	The following is from an actual animation file.
	V3.00
	150 2
	obj01: %jet.1 %top
	obj02: %dodec.2 %top
	frame00001: 1
	     obj01: 1.000001
		    -0.319034 0.851279 0.083420 0.408145
		    -3.847656 2.343750 0.000000
	     obj02: 1.000000
		    0.000000 0.000000 0.000000 1.000000
		    0.000000 0.000000 0.000000
	frame00002: 0
	     obj01: 0.995840
		    -0.320958 0.849079 0.072465 0.413279
		    -3.782710 2.289426 0.017227
	     obj02: 0.999938
		    0.000133 -0.000145 -0.000006 1.000000
		    0.000974 0.001045 0.000894
		       :
		       :
	frame00150: 1
	     obj01: 1.000002
		    0.093315 -0.873631 -0.019413 -0.477162
		    3.691406 2.910156 0.000000
	     obj02: 1.431681
		    0.145827 -0.578138 -0.359000 0.718060
		    -2.349367 0.213579 1.961043
EOF