Things In Motion, version 2.0

TIM (Things In Motion) is a set of related programs whose goal is to facilitate the visualization of time-series positional data.  

The data to be displayed can be either read  from an existing file, or they can be generated by a simulation process and asynchronously displayed by a visualization process as the data are being generated. The visualization and simulation processes do not need to run on the same system;  this allows the simulation process to be run on a large remote "number-cruncher", while the visualization can be done on a local system.

TIM uses DIVERSE's dpf and dtk modules to allow the data to be viewed on systems ranging from a laptop to a multi-screen immersive display such as a CAVE(tm).

TIM reads data from two related files- an objects file and a frames file.
Before processing, each file is normalized as follows:
The objects file contains one filename per line.  The file contains data to describe a three-dimensional object which can be loaded by an OpenGL Performer file loader, such as Inventor, or 3d Studio Max.

The frames file contains positional data for the items listed in the objects file.  Each line contains seven space-delimited floating point numbers.  The first three numbers represent an (X, Y, Z) translation, where +X goes to the right, +Y goes straight ahead, and +Z goes up.  The last four numbers represent an (X, Y, Z, W) quaternion rotation in the same coordinate space.

The object file and the frames file are related as follows.  If the objects file contains the names of n files, then the first n data lines of the frames file specify the initial positions of these objects.  The second n lines in the frames file specify the objects' second position.  The third n lines in the frames file specify the objects' third position, and so forth.  All positions are absolute, not relative to earlier positions.

Here is a simple example with three objects and three frames.  The quaternion values are not normalized, but just example data.  The grey values in the objects column are not in the objects file, just the first three lines are, but help show how the objects correspond to the data in the frames file


objects file
frames file
start of first frame
exampleData.iv
1 2 3    1 2 3 4

bar.iv
0 2 4   1 0 0 0

baz.iv
3 6 9   1 0 1 0
start of second frame
exampleData.iv
2 3 4   2 3 4 5

bar.iv
1 3 5   0 1 0  0

baz.iv
4 7 10   1 0 1 0
start of third frame
exampleData.iv 3 4 5   3 4 5 6

bar.iv 2 4 6   0 0 1 0

baz.iv 5 8 11  0 1 0 0

The public interface to TIM is the tim.2 shell script, which incorporates most of TIM's functionality in a single command.  The shell script calls private utility programs;  these are also available to "power users" who wish to write their own shell scripts, or use the commands directly.

Here's the syntax of the tim.2 command:

tim.2
(--objects|-o) objFile
[(--frames|-f) framesFile]
[--verbose|-v]
[(--sequence|-s) seqFile]
[(--time|-t) t]
[--first f]
[--last l]
[--every e]
[(--nodes|-n) nodeFile]
[(--segment|-S) segName]
[(--bound|-b) r]
[(--center|-c) x y z]
[(--examine|-e)]
[--savgfly option]
[(--diversifly|-d) option ...]

where:
framesFile is the name of a TIM frames file.  If framesFile is "-", or this parameter is not specified, standard input is used.
objFile is the name of a sequence file.
seqFile is the name of a sequence file.
t is the time between frames, in floating point seconds.  If not supplied, the default time is .03 seconds
f is the number of frames to discard from the beginning of the frames data
l is the number of frames to discard from the end of the frames data
e discards all but every "e"th frame of frames data.  If --first is also given, --first is applied before --every
r is the radius of a bounding sphere- data will be scaled to fit within this sphere.
x y z is the dpf coordinate that will become the center of the data.
nodeFile is the name of a dpfShmDCS nodes file.  If not supplied, a temp file will be created
segName is the name of a DTK shared memory segment.  If not supplied, "position" will be used

If --sequence is specified, a sequence file is created but neither savgfly nor diversifly are run

If the --savgfly option is specified, the savgfly program (which in turn invokes diversifly) is used to view the data with the supplied argument.  If not, the diversifly program is used directly.

If --examine is specified, data will be bounded inside a sphere with radius 1, and center at 0, 2, 0 when diversifly is run.

All options after the --diversifly option are passed verbatim as options to the diversifly command, either directly or via savgfly.  Options can also include extra files to be loaded.

The --bound and --center options are implemented by passing --scale and --center options to diversifly.  If these options are also specified in the --diversifly options, they will overwrite the --scale and --center diversifly options generated by tim's --bound and --center options

The --sequence option conflicts with the --bound, --center, --examine --savgfly and --diversifly options.

The --examine --bound and --last options conflict with standard input for the frames data.

Below are the private binaries used by tim.2:

timToNodes
reads an objects file and creates a "nodes" file as used by the DIVERSE dpfShmDCSloader DSO.   Here's its syntax:
timToNodes [--segment s] [--parent n] [--verbose]
where:
s is the segment name
n is the name of the parent node
If the segment name is not specified, "position" is used.  If the parent name is not specified, "world" is used.

timToSeq reads both the frames and objects file to create a "sequence" file as used by the libpfseq Performer file loader.  Here's its syntax:
timToSeq --objects objFile --frames frameFile --sequence seqFile [--time t] [--verbose] [--noclobber]
where:
t is the time between frames- if not specified it uses the libpfseq default
objFile is an existing "tim" objects file
frameFile is an existing "tim" frames file. if framesFile is "-", standard input will be used.
seqFile is the new "seq" file.  if seqFile is "-", standard output will be used. 
No checking is done to see if seqFile already exists unless "noclobber" is set

sim reads frames data from standard input and writes it into DTK shared memory.  Here's its syntax:
sim [--time t] [--number d] segname
where:
t is the time (float seconds) to wait between reads
d is the number of positional elements in the shared memory segname
if t is omitted, 1/30th of second is used
if d is omitted, the size of segname is used if it exists
segname is created if it doesn't exist
if neither d is given and segname doesn't exist, a size of one coordinate is used for the new segment

checkData reads a TIM frames file via standard input and writes the frames data to standard output.  It checks for syntax and normalizes the data; blank lines, and anything after and including a # will be ignored.  It exits with zero if the data are valid.

eulerToQuat reads lines of data from standard input, each line containing three floating point numbers representing an Euler angle, and for each line of input writes four floating point numbers to standard output containing the equivalent quaternion rotation.

quatToEuler reads lines of data from standard input, each line containing four floating point numbers representing a quaternion rotation, and for each line of input writes three floating point numbers to standard output containing the equivalent Euler angle.

xyzEulerToxyzQuat reads lines of data from standard input, each line containing six floating point numbers representing a position and an Euler angle, and for each line of input writes seven floating point numbers to standard output containing the same position and equivalent quaternion rotation.

xyzQuatToxyzEuler reads lines of data from standard input, each line containing seven floating point numbers representing a position and quaternion rotation, and for each line of input writes six floating point numbers to standard output containing the same position and equivalent Euler angle.

xyzToxyzQuat reads lines of data from standard input, each line containing three floating point numbers representing a position, and for each line of input writes seven floating point numbers to standard output containing the same position, and a null quaternion rotation.

every reads lines of data from standard input, and writes every nth line to standard output.  Here's its syntax:

every [--verbose] [--group g] n
where:
n is the number of lines to skip in a loop
g is the number of lines to group together to count as one line- default is 1

first  reads lines of data from standard input, discards the first n lines, and sends the rest of the data to standard output.  Here's its syntax:

first [--verbose] [--group g] n
where:
n is the number of lines to skip at the beginning of the data
g is the number of lines to group together to count as one line- default is 1

last  reads lines of data from standard input, discards the last n lines, and sends the rest of the data to standard output.  Here's its syntax:

last [--verbose] [--group g] n
where:
n is the number of lines to skip at the end of the data
g is the number of lines to group together to count as one line- default is 1

loop reads lines of data from standard input, and when EOD is reached, writes the data in a loop to standard output.  Here's its syntax:
loop [--sleep z]
where:
z is the number of seconds (float) to wait before starting to write data- default is to not sleep

TIM's private directory contains a shell script, exampleData.sh, which demonstrates the many ways to use TIM.  Run the shell script from the private directory.

Here are a few examples of using the tim.2 command:

Just using tim to create a sequence file for later viewing:
tim.2 --time $time \
    --frames exampleData.frames \
    --objects exampleData.objects \
    --sequence exampleData.seq --verbose

Using tim.2 to create a visualization using diversifly:
tim.2 --examine --time $time \
    --frames exampleData.frames \
    --objects exampleData.objects \
    --verbose

Using tim.2 to create a visualization using savgfly (a NIST diversifly wrapper):
tim.2 --examine --savgfly trackball --time $time \
    --frames exampleData.frames \
    --objects exampleData.objects \
    --verbose

If a program generates frames data and writes it to standard output, you can use TIM to view the data.
yourProgram | tim.2 --time $time \
    --objects exampleData.objects \
    --verbose

If the program that generates the data is on a remote networked machine, DTK's remote shared memory can be used to view the data across the network.

The visualization system needs to create a "nodes" file for the dpfShmDCSLoader DSO from the objects file.  This file specifies the scenegraph nodes to be animated, and what DTK shared memory segment will contain the data to animate them.  The nodes file only needs to be created once:
timToNodes --segment exampleData  < exampleData.objects > exampleData.nodes

The remote machine then writes the data to shared memory like this:
remoteProcess | sim --number 6 exampleData
this indicates that there are 6 objects being moved, and the data will be stored in the shared memory file named exampleData

The visualization system would do this to display the data:
env DPF_SHM_DCS=exampleData.nodes \
DPF_DSO_FILES=desktopGroup:dpfShmDCSloader \
diversifly NULL


  Authors:
      John Kelso, Steve Satterfield
      Scientific Applications & Visualization Group
           SAVG web page: http://math.nist.gov/mcsd/savg/
      Mathematical & Computational Science Division
           MCSD web page: http://math.nist.gov/mcsd/
      National Institute of Standards and Technology
           NIST web page: http://www.nist.gov/


  For information about this software contact John Kelso, kelso@nist.gov

"This software was developed at the National Institute of Standards and Technology by employees of the Federal Government in the course of their official duties. Pursuant to title 17 Section 105 of the United States Code this software is not subject to copyright protection and is in the public domain. This is an experimental system.  NIST assumes no responsibility whatsoever for its use by other parties, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic.
We would appreciate acknowledgement if the software is used."