Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3DC Animated Model File Format

Animated variant of the 3D model format. Same binary layout — identical header and section structure — but with multiple animation frames.

Differences from .3D

Aspect.3D.3DC
FramesAlways 12+ (animated)
frame_type (frame 0)02, 4, or 8
Animated frame dataNoneFrames 1+ with compressed or full-precision geometry
Section4 (SubObject BVH)Present (v5.0)Always absent (offset=0, count=0)
Vertex-normal indirection tablePresentAlways absent (offset=0)
Versionv4.0 or v5.0Always v4.0

All shared structures (header, face data, vertex coordinates, face normals, vertex normals, texture encoding) are documented in 3D.md.

Animation Frame Data

The frame data array at offset_frame_data contains num_frames × 16-byte records (see 3D.md — Frame Data for the record layout).

Frame 0 always points to the base geometry (same as .3D files). Frames 1+ contain per-frame vertex positions and face normals in a compact encoding determined by frame_type:

frame_type Values

ValueMeaningFrame 1+ vertex encodingFrame 1+ normal encoding
2Compressed animationi16 × 3 (6 bytes/vertex)10-10-10-2 packed (4 bytes/face)
4Full-precision animationi32 × 3 (12 bytes/vertex)10-10-10-2 packed (4 bytes/face)
8Static (single-frame .3DC)N/AN/A

frame_type is only meaningful in frame 0’s record. Frame 1+ records always have frame_type = 0.

10-10-10-2 Packed Normal Format

Used for face normals in frames 1+:

Bits  0- 9: nx (10-bit signed, subtract 1024 if >= 512)
Bits 10-19: ny (10-bit signed, subtract 1024 if >= 512)
Bits 20-29: nz (10-bit signed, subtract 1024 if >= 512)
Bits 30-31: unused (values: 0 and 3)

Each component is divided by 256.0 to produce the final normal vector.

The engine’s normal decoder extracts the three 10-bit signed components via sign-extending shifts and discards bits 30–31:

nx = (float)((packed << 22) >> 22) * scale;   // bits  0–9, sign-extended
ny = (float)((packed << 12) >> 22) * scale;   // bits 10–19, sign-extended
nz = (float)((packed <<  2) >> 22) * scale;   // bits 20–29, sign-extended
// bits 30–31 are shifted out by << 2 — never read

The values (0 and 3) are likely packing artifacts — 3 (0b11) can result from sign extension during the build tool’s encoding step. Parsers should mask or discard these bits.

Section Layout

Same as 3D.md — Section Layout, but with animated frame data inserted and .3D-only sections absent:

  1. Face Data — at 0x40
  2. Vertex Coordinates — base frame positions
  3. Face Normals — base frame normals
  4. Frame Datanum_frames × 16-byte records
  5. Animated Frame Vertex/Normal Data — frames 1+ geometry
  6. Vertex Normals — per-vertex normals (f32 × 3)

External References