Skip to content

CEM v2 Format

zocker-160 edited this page Aug 28, 2020 · 10 revisions

The CEM v2 File Format

CEM is the model file format used in Empire Earth.

big thanks to @coderbot16 and the community for the help

by zocker-160 and @coderbot16


everything is in little endian

important: one CEM file can include multiple files + headers

The Header

CEM files start with a header, including the magic number, version, and model data as well as general model data.

Type Name Description
u32 magic number Should always match 0x464D5353 or SSMF
u32 CEM version in this case 2
u32 triangles / faces How many triangles the model has in the largest LOD level
u32 vertices How many vertices the model has in each frame
u32 tag points How many tag points the model has in each frame
u32 materials How many materials the model has, must be at least 1
u32 frames How many frames the model has, must be at least 1
u32 child models How many children models this file has
u32 lod levels The number of levels of detail this model has, must be at least 1
u32 length of name length of name + 1 (delimiter 0x00)
string name The model's name
point3 center The center of the bounding box that contains every vertex in the model

Length (in bytes)

header = 52 + length of name

so if name is Scene Root --> header = 63 bytes

Points and Vectors

Points, otherwise known as point3, represent a 3D point in space.

Type Name Description
f32 x X coordinate in space
f32 y Y coordinate in space
f32 z Z coordinate in space

Vectors (vector3) have the same format.

The Indices

Each level of detail contains a list of triangles, where each triangle is defined by 3 u32s representing each vertex index. This corresponds to the concept of index buffers in computer graphics.

Organization:

  • A single level of detail
    • u32: number of triangles in this level of detail
    • array of u32: the indices for each triangle, has a length of triangle count * 3
  • Another level of detail
    • the number of LODs corresponds to the count in the header

Length (in bytes)

length of one LOD level = 4 + triangle count * 3 * 4

total length = SUM of all LOD levels

The Materials

Next, the CEM file has an array of materials, with the number of materials specified in the header.

Important note! You MUST add vertex_offset to each of the indices in the corresponding triangles of each LOD level or else the parsed model will look very broken!

Type Name Description
u32 length of name length of name + 1 (delimiter 0x00)
string name The name of the material
u32 texture index The index of the texture used by this material
array triangle selections An array of (u32 offset, u32 length) pairs for each LOD level (1)
u32 vertex offset The number to add to each triangle's vertex index
u32 vertex count The number of vertices that this material applies to
u32 length of texture name length + 1 (delimiter 0x00)
string texture name The name of the texture used by this material

(1) this defines which triangles get selected out of the indices array of each LOD level

the offset + length of material 1 should be the same as the offset of material 2 etc.

Length (in bytes)

material = 20 + lod levels * 8 + length of name + length of texture name

total length = SUM of all materials (usually 2)

Tag Point Names

After the materials the CEM file has an array of strings corresponding to each tag point, giving each tag point a name.

Type Name Description
u32 length of name length + 1 delimiter 0x00
string name name of tag point

Frames

This is the most important part of the file, containing all the vertex data. CEM files use frame based animation (also known as mesh deformation animation) meaning that instead of having a system of formal bones, animations are created by simply changing the vertices and tag points that the model uses.

Type Name Description
f32 radius squared Contains the maximum distance from the center point to any vertex, squared (1)
vertex array vertices The frame's vertices
point3 array tag points Positions of each tag point
4x4 matrix transform The matrix used to transform the vertices before rendering. Usually the identity matrix.
point3 lower bound Minimum values for each coordinate, forms the bounding box
point3 upper bound Maximum values for each coordinate, forms the bounding box

(1) it seems this is being used to calculate the selection range for the object (if you set it to 0, you cannot select the model anymore by clicking on it)

Vertices

Each vertex contains position, normal, and texture data.

Type Name Description
point3 vertex The position of this vertex in space
vector3 normal The normal vector for this vertex, used for lighting
point2 texture Contains the texture coordinate of this vertex. The material defines which texture this refers to. U (x) and V (y) are within the range 0.0 and 1.0. Note that you may need to flip the V coordinate with the expression 1.0 - v.

Matrices

4x4 matrices are used to transform vertices. (see transformation matrix ) They are in column major and in a homogeneous form. (see homogeneous coordinates )

It has to be applied to all vertices, otherwise the child models won't be in the right position or have the right rotation.

The format is an array of 16 f32s corresponding to each element.

Data types overview

data type width s / u range
s8 8 bits (1 byte) signed -128 to +127
s16 16 bits (2 bytes) signed -32,768 to +32,767
s32 32 bits (4 bytes) signed -2,147,483,648 to +2,147,483,647
s64 64 bits (8 bytes) signed −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
u8 8 bits (1 byte) unsigned 0 to +255
u16 16 bits (2 bytes) unsigned 0 to +65,535
u32 32 bits (4 bytes) unsigned 0 to +4,294,967,295
u64 64 bits (8 bytes) unsigned 0 to +18,446,744,073,709,551,615
point 1,2,3 or 4 bytes generic
f32 4 bytes IEEE 754 signed