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:
- Everything including and after a pound sign (#) is discarded,
enabling comments
- Multiple spaces and TABs are treated as a single space, and
leading and trailing spaces are ignored
- Resulting blank lines are ignored
- A back-slash (\) can be used to include spaces and pound signs in
file names, by preceeding the space or pound sign by a back-slash
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."