FORM TDDD is used by Impulse's Turbo Silver 3.0 for 3D rendering
data. TDDD stands for "3D data description". The files contain
object and (optionally) observer data.
Turbo Silver's successor, "Imagine", uses an upgraded FORM TDDD
when it reads/writes object data.
Currently, in "standard IFF" terms, a FORM TDDD has only two chunk
types: an INFO chunk describing observer data; and an OBJ chunk
describing an object heirarchy. The INFO chunk appears only in
Turbo Silver's "cell" files, and the OBJ chunk appears in both
"cell" files and "object" files.
The FORM has an (optional) INFO chunk followed by some number of
OBJ chunks. (Note: OBJ is followed by a space -- ckID = "OBJ ")
The INFO and OBJ chunks, in turn, are made up of smaller chunks with
the standard IFF structure: .
The INFO "sub-chunks" are relatively straightforward to interpret.
The OBJ "sub-chunks" support object heirarchies, and are slightly
more difficult to interpret. Currently, there are 3 types of OBJ
sub-chunks: an EXTR chunk, describing an "external" object in a
seperate file; a DESC chunk, describing one node of a heirarchy;
and a TOBJ chunk marking the end of a heirarchy chain. For each
DESC chunk, there must be a corresponding TOBJ chunk. And an
EXTR chunk is equivalent to a DESC/TOBJ pair.
In Turbo Silver and Imagine, the structure of the object heirarchy
is as follows. There is a head object, and its (sexist) brothers.
Each brother may have child objects. The children may have
grandchildren, and so on. The brother nodes are kept in a doubly
linked list, and each node has a (possibly NULL) pointer to a
doubly linked "child" list. The children point to the "grandchildren"
lists, and so on. (In addition, each node has a "back" pointer to
its parent).
Each of the "head" brothers is written in a seperate OBJ chunk,
along with all its descendants. The descendant heirarchy is
supported as follows:
for each node of a doubly linked list,
- 1) A DESC chunk is written, describing its object.
- 2) If it has children, steps 1) to 3) are performed
for each child.
- 3) A TOBJ chunk is written, marking the end of the children.
For "external" objects, steps 1) to 3) are not performed, but
an EXTR chunk is written instead. (This means that an external
object cannot have children unless they are stored in the same
"external" file).
The TOBJ sub-chunks have zero size -- and no data. The DESC
and EXTR sub-chunks are made up of "sub-sub-chunks", again,
with the standard IFF structure: .
( "External" objects were used by Turbo Silver to allow a its
"cell" data files to refer to an "object" data file that is
"external" to the cell file. Imagine abandons the idea of
individual cell files, and deals only in TDDD "object" files.
Currently, Imagine does not support EXTR chunks in TDD files.)
Reader software WILL FOLLOW the standard IFF procedure of
skipping over any un-recognized chunks -- and "sub-chunks"
or "sub-sub-chunks". The field indicates how many
bytes to skip. In addition it WILL OBSERVE the IFF rule that
an odd may appear, in which case the corredponding
field will be padded at the end with one extra byte to
give it an even size.
Now, on with the details.
First, there are several numerical fields appearing in the data,
describing object positions, rotation angles, scaling factors, etc.
They are stored as "32-bit fractional" numbers, such that the true
number is the 32-bit number divided by 65536. So as an example,
the number 3.14159 is stored as (hexadecimal) $0003243F. This
allows the data to be independant of any particular floating point
format. And it (actually) is the internal format used in the
"integer" version of Turbo Silver. Numbers stored in this format
are called as "FRACT"s below.
Second, there are several color (or RGB) fields in the data.
They are always stored as three UBYTEs representing the red,
green and blue components of the color. Red is always first,
followed by green, and then blue. For some of the data chunks,
Turbo Silver reads the color field into the 24 LSB's of a
LONGword. In such cases, the 3 RGB bytes are preceded by a
zero byte in the file.
The following "typedef"s are used below:
typedef LONG FRACT; /* 4 bytes */
typedef UBYTE COLOR[3]; /* 3 bytes */
typedef struct vectors {
FRACT X; /* 4 bytes */
FRACT Y; /* 4 bytes */
FRACT Z; /* 4 bytes */
} VECTOR; /* 12 bytes total */
typedef struct matrices {
VECTOR I; /* 12 bytes */
VECTOR J; /* 12 bytes */
VECTOR K; /* 12 bytes */
} MATRIX; /* 36 bytes total */
typedef struct _tform {
VECTOR r; /* 12 bytes - position */
VECTOR a; /* 12 bytes - x axis */
VECTOR b; /* 12 bytes - y axis */
VECTOR c; /* 12 bytes - z axis */
VECTOR s; /* 12 bytes - size */
} TFORM; /* 60 bytes total */
The following structure is used in generating animated cells
from a single cell. It can be attached to an object or to the
camera. It is also used for Turbo Silver's "extrude along a
path" feature. (It is ignored & forgotten by Imagine)
typedef struct story {
UBYTE Path[18]; /* 18 bytes */
VECTOR Translate; /* 12 bytes */
VECTOR Rotate; /* 12 bytes */
VECTOR Scale; /* 12 bytes */
UWORD info; /* 2 bytes */
} STORY; /* 56 bytes total */
The Path[] name refers to a named object in the cell data.
The path object should be a sequence of points connected
with edges. The object moves from the first point of the
first edge, to the last point of the last edge. The edge
ordering is important. The path is interpolated so that
the object always moves an equal distance in each frame of
the animation. If there is no path the Path[] field should
be set to zeros.
The Translate vector is not currently used.
The Rotate "vector" specifies rotation angles about the
X, Y, and Z axes.
The Scale vector specfies X,Y, and Z scale factors.
The "info" word is a bunch of bit flags: