The information on this page applies both to 'Lifeforms' style SEQ files, and to the new ActiveWorlds (Hamfon) style text SEQ introduced in AW 3.3. Please note that 'joint' and 'limb' are two names for the same thing.
Contents:
Download the SeqFileViewer 2.2 to view (as text) and edit the information in a binary or text seq file.
Traditionally there was only one format for SEQ files: the so called 'Lifeforms' binary SEQ file.
With the appearance of Active Worlds 3.3, Nelson Crowle (HamFon) introduced a text format, which allows more flexibility: all 'joints' (there called 'limbs') can be displaced as well as rotated, and there are provisions for rescaling them too (not yet implemented in 3.3 or 3.4).
Active Worlds only uses part of the information in this SEQ file to animate avatars. The root joint is usually mentioned twice, in the header and in the Rotations section. It does not seem to matter to AW if it is left blank in the header (AW will use the 'pelvis'), and it may be omitted in the Rotations section if it is not needed. For example, qwave.seq specifies a root joint 'pelvis', but only defines data for back, lfshoulder, lfelbow and lfwrist. Some Seq files have an anomaly: the Model is called 'pelvis', the root joint is left blank (gray01.seq and others). The Location data (groups 1 to 3) refer to this root object and should normally be 0, 0, 0 for the first frame: units represent metres as experienced in Active Worlds. Facing is ignored, the Rotation quaternions for the pelvis (if present) are used to regulate facing. The last groups marked unknown are probably ignored as well.
The names of the joints are important: Active Worlds will ignore all data which refers to joint names it does not recognise. The hierarchy is undefined in the SEQ file because it is already defined in the RWX file, so tags may be applied to any joint (clump) in any order (except for the pelvis, which is always the root), but are usually applied using the humanoid model. The standard tag numbers (used in the RWX file), joint names (used in the seq file) and description for a humanoid avatar are:
tag number in RWX clump |
joint/limb name in SEQ |
description and function in a normal humanoid avatar |
---|---|---|
1 | pelvis | this is the root joint |
2 | back | torso, child of pelvis |
3 | neck | child of back |
4 | head | child of neck (or of neck2 if used) |
5 | rtsternum | right sternum, child of back, often omitted |
6 | rtshoulder | right upper arm, child of rtsternum (or of back if rtsternum is missing) |
7 | rtelbow | right lower arm, child of rtshoulder |
8 | rtwrist | right hand, child of rtelbow |
9 | rtfingers | right fingers, child of rtwrist, usually absent |
10 | lfsternum | left sternum, child of back, often omitted |
11 | lfshoulder | left upper arm, child of lfsternum (or of back if lfsternum is missing) |
12 | lfelbow | left lower arm, child of lfshoulder |
13 | lfwrist | left hand, child of lfelbow |
14 | lffingers | left fingers, child of lfwrist, usually absent |
15 | rthip | right upper leg, child of pelvis |
16 | rtknee | right lower leg, child of rthip |
17 | rtankle | right foot, child of rtknee |
18 | rttoes | right toes, child of rtankle, often omitted |
19 | lfhip | left upper leg, child of pelvis |
20 | lfknee | left lower leg, child of lfhip |
21 | lfankle | left foot, child of lfknee |
22 | lftoes | left toes, child of lfankle, often omitted |
23 | neck2 | the neck can be hinged using this tag as child of neck: in this case the head is a child of neck2 |
24 | tail | optional, child of pelvis |
25 | tail2 | optional, can be attached to tail |
26 | tail3 | optional, can be attached tail2 |
27 | tail4 | optional, can be attached tail3 |
28 | obj1 | optional prop, child of any other |
29 | obj2 | optional prop, child of any other |
30 | obj3 | optional prop, child of any other |
the following 12 tags were introduced in AW 3.3, but they were not working properly for text SEQs. As from AW 3.4 (browser 494 or 495?) they work both for binary as for text SEQs. | ||
31 | hair | |
32 | hair2 | |
33 | hair3 | |
34 | hair4 | |
35 | rtbreast | |
36 | lfbreast | |
37 | rteye | |
38 | lfeye | |
39 | lips | |
40 | nose | |
41 | rtear | |
42 | lfear |
All numeric formats in the SEQ file are bigendian (Macintosh), to read them
on Intel machines reverse the order of the bytes. Locations (positioning) are
relative to the resting position of the Pelvis (root joint), rotations are
relative to the resting rotation of the joints. Frame numbers start by 1 (not
0).
# of bytes | format | description | ||
---|---|---|---|---|
Header | ||||
4 | integer | header, 7F7F7F79 and 7F7F7F7A | ||
2 | integer | total number of frames, includes key frames (mapped in the seq) and all others, i.e. is the number of the last frame. | ||
4 | integer | number of joints. NJoints | ||
2 | integer | length of next string, including trailing nul-byte. x | ||
x | string | name of model + nul-byte | ||
2 | integer | length of next string, including trailing nul-byte. y | ||
y | string | name of root-joint, including trailing nul-byte. | ||
The Rotations of joints are defined as quaternions in specific frames. Intermediate frames are interpolated by the renderer. | ||||
Joints loop (1st loop), NJoint times | ||||
2 | integer | length of next string, including trailing nul-byte. x | ||
x | string | name of joint, including trailing nul-byte. In the first iteration, is usually the name of the root-joint (same as previous string) | ||
4 | integer | data length in each iteration: 16 bytes, corresponds to 4 * 4 bytes of the quaternion floats | ||
4 | integer | number of frames in which this joint has quaternions defined. NFrame | ||
Inner Frame loop (inside Joints loop), NFrame times | ||||
4 | integer | frame number | ||
4 | float | data: Rotation Quaternion of joint. Quaternion W | ||
4 | float | data: Quaternion X | ||
4 | float | data: Quaternion Y | ||
4 | float | data: Quaternion Z | ||
End of Inner Frame loop | ||||
End of Joints loop | ||||
Next, there are a variable number of blocks of frame loops. For example, the dredd03.seq has 9 blocks: blocks 1 to 3 indicate the position of the model in metres from the origin of the scene (not in Dekametres, as are used in the RWX and world units), block 4 has a rotation Quaternion (Facing), blocks 5 to 8 have each a 4-byte data field, block 9 has a rotation Quaternion. The first 3 (or 4?) are probably mandatory for ActiveWorlds. I have counted up to 9 blocks (dredd03.seq). Note that very few files omit these blocks altogether: typically the 'wave' animations. These anomalous SEQ files crash LifeForms, but Accutrans 3D (from version 6.32) accepts them. If the blocks are not omitted, they must contain at least one set defining the X, Y, Z Location for frame number 1, otherwise the positioning of the avatar in animation is random. | ||||
4 | integer | number of blocks of information: variable | ||
Block 1: Location X | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Location X Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: Location X | ||
End of Loop | ||||
Block 2: Location Y | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Location Y Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: Location Y | ||
End of Loop | ||||
Block 3: Location Z | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Location Z Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: Location Z | ||
End of Loop | ||||
The rest of the file is not used by Active Worlds | ||||
Block 4: Facing | ||||
4 | integer | data length: 16 bytes, = 4 bytes * 4 floats | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: Orientation Quaternion of model (not used in AW?). Quaternion W | ||
4 | float | data: Quaternion X | ||
4 | float | data: Quaternion Y | ||
4 | float | data: Quaternion Z | ||
End of Loop | ||||
Block 5: unknown | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: unknown | ||
End of Loop | ||||
Block 6: unknown | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: unknown | ||
End of Loop | ||||
Block 7: unknown | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: unknown | ||
End of Loop | ||||
Block 8: unknown | ||||
4 | integer | data length: 4 bytes (float) | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: unknown | ||
End of Loop | ||||
Block 9: unknown quaternion | ||||
4 | integer | data length: 16 bytes, = 4 bytes * 4 floats | ||
4 | integer | number of frames in the block. f | ||
Loop, f times | ||||
4 | integer | frame number | ||
4 | float | data: unknown Quaternion W | ||
4 | float | data: unknown Quaternion X | ||
4 | float | data: unknown Quaternion Y | ||
4 | float | data: unknown Quaternion Z | ||
End of Loop | ||||
End of file |
This format was introduced by HamFon (Nelson Crowle) in AW 3.3. It is an ASCII file, that can be edited with any text editor (for example, Notepad). It consists of lines of text, each line ending in a carriage-return + line-feed pair, as is usual in Windows ASCII texts. It contains similar but not identical information to the binary format. In fact, it allows translations of 'limbs' (in binary format called 'joints'), as well as the traditional rotations. The format also allows information for scaling, but this has not been implemented (yet) by Active Worlds (scaling information, if present, is ignored).
See example below. The first line contains a magic word AWSQ, the version number Version=1, the number of limbs Limbs=7, and the duration in milliseconds Duration=4633. Next follow the limb sections (7 in this case), each with its own header (shown in bold here). The limb header has the limb name and the number of frames. Within a limb section, each line represents a frame (or keyframe): first number (integer) is the time in milliseconds, next four numbers (in blue here) represent the rotation in axis-angle notation (x, y, z, angle in degrees), the next three numbers are the xyz translations (in AW coordinates or decametres). Three more numbers may follow for xyz scaling: 1.0 1.0 1.0 is default (this is optional and is not yet implemented by AW, and is not shown in this example).
AWSQ Version=1 Limbs=7 Duration=4633 pelvis frames=4 0 0.000000 0.000000 1.000000 0.0000 0.0153 0.0000 -0.0043 1700 0.000000 0.000000 1.000000 0.0000 0.0153 0.0000 -0.0043 3133 0.005932 0.000000 -0.999982 349.1282 0.0269 -0.0008 -0.0086 4633 0.005932 0.000000 -0.999982 349.1282 0.0269 -0.0008 -0.0086 lfhip frames=4 0 0.036796 -0.028458 -0.998918 353.6962 0.0000 0.0000 0.0000 1700 0.036796 -0.028458 -0.998918 353.6962 0.0000 0.0000 0.0000 3133 -0.226745 0.004188 0.973945 345.7601 0.0000 0.0000 0.0000 4633 -0.226745 0.004188 0.973945 345.7601 0.0000 0.0000 0.0000 lfknee frames=4 0 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 1700 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 3133 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 4633 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 lfankle frames=3 0 0.000000 0.000000 1.000000 356.6163 0.0000 0.0000 0.0000 3000 0.723511 -0.016471 -0.690117 356.2214 0.0000 0.0000 0.0000 4633 0.723511 -0.016471 -0.690117 356.2214 0.0000 0.0000 0.0000 rthip frames=4 0 0.000000 0.000000 1.000000 354.5141 0.0000 0.0000 0.0000 1700 0.000000 0.000000 1.000000 354.5141 0.0000 0.0000 0.0000 3133 0.543298 0.155699 0.824976 332.1506 0.0000 0.0000 0.0000 4633 0.543298 0.155699 0.824976 332.1506 0.0000 0.0000 0.0000 rtknee frames=4 0 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 1700 0.000000 0.000000 1.000000 0.0000 0.0000 0.0000 0.0000 3133 -1.000000 0.000000 0.000000 342.8727 0.0000 0.0000 0.0000 4633 -1.000000 0.000000 0.000000 342.8727 0.0000 0.0000 0.0000 rtankle frames=3 0 0.000000 0.000000 -1.000000 354.2058 0.0000 0.0000 0.0000 3000 0.149576 -0.018882 -0.988570 352.2866 0.0000 0.0000 0.0000 4633 0.149576 -0.018882 -0.988570 352.2866 0.0000 0.0000 0.0000
The format requires that at least TWO frames be defined for each limb. Frame count starts at 0 (milliseconds), this first frame at time 0 must be defined for each limb. The end frame must be within the range specified in the first line of the file (in this case, between 1 and 4633), and must be at time > 0. Not all limbs need to have the same number of frames at the same times.
The limb names are as specified in the binary SEQ section. As from AW 3.4, 12 extra limbs may be used.
Notice that in this example, only the pelvis has translations (like in binary SEQs). But all other limbs can be translated too, if necessary. The order of execution is (I think, I need to confirm this, feedback is welcome): scaling (not used), rotation on own pivot, translation of pivot relative to parent limb.
Empty or comment lines are ignored (but the first line must be the file header). A comment line can start with # or //, other symbols are possible according to Hamfon, not quite clear which.
I have used spaces as separators. According to HamFon, other separators are also valid: TAB, comma, and a few more. I stick to spaces :)
Binary SEQs can be fully represented by text SEQs, i.e. you can change a binary SEQ into a text SEQ without loss of information.
Not so from text to binary SEQ. (1) Text SEQs carry information for 1000 frames per second, binary SEQs for 30 frames per second, so some frames may be lost when converting to binary format, and the timing is rounded off to the nearest 1/30th of a second. (2) Text SEQs have information for translations (and scaling) for all limbs, binary SEQs carry only information for the translations of the pelvis.