MREA (Metroid Prime 3)

Revision as of 08:24, 23 May 2016 by >Aruki (→‎Section Numbers)

See MREA (File Format) for the other revisions of this format.

The MREA format, which defines areas/levels, received another large layout overhaul in Metroid Prime 3. The level geometry data received the biggest update, with a new material format, lot of things being moved around, and a few entirely new sections being introduced. This article covers Metroid Prime 3, the MP3 E3 prototype, and Donkey Kong Country Returns.


This file format needs more research
There are a few sections we know nothing about.


Format

MREA files are split up into a number of 32-byte aligned sections. Every section both starts and ends on a 32-byte boundary. These are used to separate different parts of the file; different types of sections typically indicate different sets of data. The header declares the section count and the size of each one; using these is the only way to navigate the file.

Header

The header is identical between MP3 and DKCR.

Offset Type Size Description
0x0 u32 4 Magic Number; always 0xDEADBEEF
0x4 u32 4 Version; see hub article
0x8 float[12] 48 Transform matrix (transform of the area in world space)
0x38 u32 4 Mesh count
0x3C u32 4 Layer count
0x40 u32 4 Section count (SC)
0x44 u32 4 Compressed block count
0x48 u32 4 Section number count
0x4C u32[5] 0x14 Padding
0x60 u32[SC] - Section sizes
End of main header data; pad to 32 bytes before compressed section definitions

Compressed Blocks

Compressed blocks are defined in the same manner as Metroid Prime 2. The MREA format contains compressed blocks that can each contain a number of regular file sections within them. These blocks are compressed using segmented LZO1X-999 in Metroid Prime 3, and segmented zlib in Donkey Kong Country Returns. Compressed blocks are padded to 32 bytes, but their padding is located at the beginning of the block rather than the end, so it's required to account for the padding before you start decompressing. The compressed data is segmented, which means there's multiple segments of data that are compressed/decompressed separately. Each segment starts with a 16-bit size value. The size value is signed; a negative value indicates the segment is not compressed (this is done when compressing a segment doesn't reduce its size). Each segment is 0x4000 bytes large when decompressed (except the last one).

Compressed blocks are defined after the main header. After reading them, pad to 32 bytes before the section numbers portion of the header starts.

Offset Type Count Name Notes
0x0 u32 1 Buffer Size This is always 0x120 bytes larger than the uncompressed size on compressed bytes, and the same value as the uncompressed size on uncompressed blocks
0x4 u32 1 Uncompressed Size
0x8 u32 1 Compressed Size This is 0 on uncompressed blocks.
0xC u32 1 Data Section Count The number of regular data sections contained in this block.
0x10 Block definition end

Section Numbers

The section numbers portion of the header indicates the section index of each major data chunk. Some of these chunks contain multiple sections; in that case the number will point to the first section of the chunk. Each number is a short 8-byte struct:

Offset Type Count Name
0x0 char 4 Section Type
0x4 u32 1 Section Index

Here are all the possible section numbers and what they are:

FourCC Description MP3 DKCR
AABB Surface Group Bounding Boxes
APTL Portal Area
COLI Collision
DEPS Dependencies
EGMC Static Geometry Map
GPUD World Geometry GPU Data
LITE Lights
LLTE Unknown
PFL2 Path
PVS! Visibility Tree
ROCT Area Octree
RSOS RSO Module List
SGEN Generated Script Objects
SOBJ Script Layers
WOBJ World Geometry Declaration (always 0, points to the materials section)

Materials

Materials are identical to those found in CMDL files.

Mesh Headers

The WOBJ sections correspond to the header for a world mesh. Those sections are unique, in that they don't have a valid section number, which is always 0. However, they are always in the sections immediately following the materials. Each mesh header takes up 4 sections - the main header, the surface offsets, the mesh info table, and the unknown table.

Main Header

Type Description Notes
long Unknown Most likely visor flags in MP3, unknown in DKCR
CTransform4f Transformation Matrix Meshes location in world space
CAABox Bounding Box Likely used for Depth sorting as in previous games.

Surface Offsets

Type Description Notes
long Surface count (SC)
long Surface Offsets[SC] Relative to the start first surface (i.e. the first offset points the the end of the first surface)

Mesh IDs

The next section contains a table of shorts that associates each surface in the mesh with a mesh ID. It starts with a 16-bit count (which always matches the mesh's surface count). The full extent of what exactly the data is and what it's used for is unknown, but it's accessed by various other components to identify world geometry.

Type Description Notes
long Unknown Usually a very similar value to the mesh ID, sometimes the same number
long Mesh ID

There is one more section after this one before the next mesh header begins that contains unknown data.

AROT

Following the WOBJ sections is usually AROT. AROT is a BSP Tree that appears to be used for shot-collision and possibly depth sorting, nothing is known about how to handle this section.

AABB

The AABB section is exactly what it sounds like, it's an array of Axis-Aligned Bounding Boxes, assembling a BVH tree. AABB starts with the number of bounding boxes with each one consisting of the following struct:

Type Description Notes
CAABox Axis Aligned Bounding Box Used to assist depth sorting, and/or collision
long Unknown The first entry in the table always covers the entire, with this value always being -1
short Self Index 1 indexed position of this particular AABB entry, but ONLY if the previous value is -1.
short Self Index 1 indexed position of this particular AABB entry, but ONLY if the previous value is -1.

GPU Description Section (GPUD)

The GPUD section is a bit confusing at first glance, however it's really no different from the previous MREA version in terms of ordering. There is also one GPUD per WOBJ section

The section order is as follows:

Vertices

The vertices are always 32bit floats, even in DKCR

Normals

The normals are always 32bit floats.

Colors

Usually 0 filled and completely unused, it's stored in MREA simply for completeness.

Float Texcoords

Metroid Prime 3 uses these exclusively, even for lightmaps, which simplifies UV handling quite a bit.

Short Texcoords

This is only used in DKCR and can be used for anything, not just for lightmaps

Submeshes

The submesh format is exactly the same as the Geometry formats found in Metroid Prime 3 and DKCR.