1. Architectural Role & Engine Purpose
The HMP (Heightmap File) format stores the massive outdoor terrain elevations, surface normal vectors, and material associations that define the expansive outdoor landscapes in Project I.G.I. 1.
Innerloop's flight simulator pedigree shines in the HMP format. Vast multi-kilometer outdoor valleys are represented
as a uniform regular grid of cells using compact 12-byte records (hmp_item_s), dynamically
tessellated via continuous level-of-detail (CLOD) algorithms at 60 FPS.
2. Binary File Layout & Memory Map Diagram
An HMP file contains a terrain grid header followed by a contiguous 2D elevation grid array:
3. Continuous Level-of-Detail (CLOD) Terrain Pipeline Diagram
The terrain engine evaluates camera distance per quad block and tessellates terrain meshes on the fly:
4. Architectural Mechanics & Engine Implementation Details
The 12-byte HMP structure is a masterclass in year-2000 graphics engine optimization:
- Fixed-Point Normals: Storing surface normal vectors as two 16-bit integers (reconstructing the third component via sqrt(1 - Nx^2 - Ny^2)) saves 8 bytes per vertex compared to 3 floating-point coordinates.
- Direct Physics Height Query: When guards or vehicles walk across the terrain, calculating height at arbitrary $(X, Z)$ coordinates requires simple bilinear interpolation between four adjacent cell elevations in $O(1)$ time.
5. C++ Struct Definitions
#pragma pack(push, 1)
struct HmpHeader {
char magic[4]; // "HMP "
uint32_t grid_width; // Number of vertices along X (e.g., 513)
uint32_t grid_height; // Number of vertices along Z (e.g., 513)
float cell_step; // Horizontal spacing in meters (e.g., 8.0f)
float min_height; // Minimum valley elevation
float max_height; // Maximum mountain elevation
};
// IGI 1 12-Byte Heightmap Cell Descriptor
struct hmp_item_s {
float elevation; // 32-bit floating-point height in meters
int16_t normal_x; // Fixed-point surface normal X
int16_t normal_y; // Fixed-point surface normal Y
uint16_t material_id; // Texture splatting index
uint16_t flags; // Surface flags
};
static_assert(sizeof(hmp_item_s) == 12, "hmp_item_s must be 12 bytes");
#pragma pack(pop)