-
Notifications
You must be signed in to change notification settings - Fork 11
ABC
This page describes the format for the ABC models found in No One Lives Forever.
All binary numeric values are in little-endian byte-order.
The file lists various sections consecutively. Each section begins with it's type, followed by an absolute offset to the next section. The data that follows in the section is dependent on the section's type (see Section Data).
Name | Type | Notes |
---|---|---|
Type | String |
|
NextSectionOffset | uint32 |
Offset is relative to the beginning of the file (absolute offset). |
Data | Variable (see below) |
Name | Type | Notes |
---|---|---|
Version | uint32 |
|
KeyframeCount | uint32 |
|
AnimationCount | uint32 |
|
NodeCount | uint32 |
|
PieceCount | uint32 |
|
ChildModelCount | uint32 |
|
FaceCount | uint32 |
|
VertexCount | uint32 |
|
WeightCount | uint32 |
|
LODCount | uint32 |
|
SocketCount | uint32 |
|
WeightSetCount | uint32 |
|
StringCount | uint32 |
See below. |
StringLengthTotal | uint32 |
See below. |
CommandString | String |
|
InternalRadius | float32 |
|
LODDistanceCount | uint32 |
|
Padding | uint8[60] |
This is a bit-field of zeroes for every file in the game. |
LODDistances | float32[LODDistanceCount] |
StringCount
is the total number of unique, non-empty strings in:
- Command string (counts as 1, unless empty)
- Node names
- Child model names
- Animation names
- Keyframe strings
StringLengthTotal
is the summed length of all of the strings.
The purpose of these two variables is unknown, but one can speculate that it's likely used for some sort of memory mapping scheme within the engine.
Name | Type | Notes |
---|---|---|
WeightCount | uint32 |
|
PieceCount | uint32 |
|
Pieces | Piece[PieceCount] |
The nodes block is a flat list of the nodes in depth-first traversal order.
Name | Type | Notes |
---|---|---|
Nodes | Node[NodeCount] |
The term "Child Models" actually seems like a bit of a misnomer, since this is used to inherit the animations of other models. A more appropriate name might be "Base Models". It's interesting to note that the number of base models appears to be one more than it actually is. The first entry appears to be a ChildModel
with an empty name.
Name | Type | Notes |
---|---|---|
Count | UINT16 |
|
ChildModels | ChildModel[ChildModelCount] |
Name | Type | Notes |
---|---|---|
Count | uint32 |
|
Animations | Animation[Count] |
Name | Type | Notes |
---|---|---|
Count | uint32 |
|
Sockets | Socket[Count] |
This section appears to be redundantly listing the Extents
of each Animation
in the file.
Name | Type | Notes |
---|---|---|
Count | uint32 |
|
AnimBindings | AnimBinding[Count] |
Strings are length-prefixed.
Name | Type | Notes |
---|---|---|
Length | uint16 |
|
Bytes | uint8[Length] |
ASCII-encoded bytes. |
Name | Type | Notes |
---|---|---|
X | float32 |
|
Y | float32 |
|
Z | float32 |
Name | Type | Notes |
---|---|---|
U | float32 |
|
V | float32 |
Name | Type | Notes |
---|---|---|
X | float32 |
|
Y | float32 |
|
Z | float32 |
|
W | float32 |
Name | Type | Notes |
---|---|---|
Material Index | uint16 |
|
Specular Power | float32 |
(0..100) |
Specular Scale | float32 |
(-10..10) |
LOD Weight | float32 |
|
Unknown | uint16 |
Always 0 . |
Name | String |
|
LODs | LOD[LODCount] |
Name | Type | Notes |
---|---|---|
FaceCount | uint32 |
|
Faces | Face[FaceCount] |
|
VertexCount | uint32 |
|
Vertices | Vertex[VertexCount] |
Name | Type | Notes |
---|---|---|
Vertices | FaceVertex[3] |
Name | Type | Notes |
---|---|---|
Texcoord | TexCoord |
|
VertexIndex | uint16 |
Name | Type | Notes |
---|---|---|
WeightCount | uint32 |
|
Weights | Weight[WeightCount] |
|
Location | Vector |
|
Normal | Vector |
Name | Type | Notes |
---|---|---|
NodeIndex | uint32 |
|
Location | Vector |
|
Bias | float32 |
Name | Type | Notes |
---|---|---|
Name | String |
|
Index | uint16 |
|
Flags | uint8 |
See flags below. |
Matrix | float32[16] |
|
ChildCount | uint32 |
Name | Type | Notes |
---|---|---|
Removable | 0x01 |
The word "removable" was gleaned from ModelEdit, where nodes with this flag are marked as (removable) . It's not yet know what this means, exactly, but it appears that the root node of every model has this flag set. |
RelativePlacement | 0x02 |
Checking a node's checkbox in ModelEdit turns this flag on. According to official Lithtech documentation: "If a node name has a check in its check box, the node will be placed relative to its parent, only the rotation will be used from the animation data. Not checking these where needed will cause bone lengths to be transferred from a child model to the parent, causing potentially strange looking scaling of a character". |
Name | Type | Notes |
---|---|---|
Extents | Vector |
|
Name | String |
|
Unknown | int32 |
Value is -1 the vast majority of the time, though there are some exceptions (see PLAYERBASE.ABC and DOG_ACTION.ABC ). |
Interpolation Time | uint32 |
The time, in milliseconds, it takes to interpolate playing this this animation. |
KeyframeCount | uint32 |
|
Keyframes | Keyframe[KeyframeCount] |
|
Keyframe Transforms | KeyframeTransform[NodeCount][KeyframeCount] |
Name | Type | Notes |
---|---|---|
Time | uint32 |
The time, in milliseconds, that this key-frame appears at in the animation. |
String | String |
This string provides animation-based cues to the game code. |
Name | Type | Notes |
---|---|---|
Location | Vector |
|
Rotation | Quaternion |
Name | Type | Notes |
---|---|---|
Name | String |
|
Extents | Vector |
|
Origin | Vector |
Name | Type | Notes |
---|---|---|
Node Index | uint32 |
|
Name | String |
|
Rotation | Quaternion |
|
Location | Vector |