forest.dat -- Procedural Vegetation Placements

1. Architectural Role & Engine Purpose

The FOREST (Dense Foliage & Procedural Tree Canopy) format populates vast outdoor forests, jungle canopies, and hillside brush in I.G.I. 2: Covert Strike.

Rather than placing trees individually via the OLM file, IGI 2 uses the dedicated FOREST format. It packs hundreds of thousands of trees into compact 28-byte records (forest_tree_record_s) with procedural wind swaying coefficients and spatial bounding clusters.

2. Binary File Layout & Memory Map Diagram

A FOREST file contains a bounding header, cluster definitions, and contiguous 28-byte tree instance records:

IGI 2 FOREST — 28-BYTE PROCEDURAL CANOPY LAYOUT 0x00: Forest Header (32 Bytes) 32 BYTES Magic "FORS" | Version | Tree Count | Spatial Cluster Count | Valley Extents Min/Max XYZ magic[4], version, tree_count, cluster_count, world_min[3], world_max[3] Spatial Cluster Table (32 Bytes per Cluster) CLUSTERS Bounding AABB boxes grouping trees into spatial sectors for rapid frustum culling Bounding center and extents for 100,000+ tree canopies Tree Instance Array: 28 Bytes per Tree (forest_tree_record_s) 28B RECORD Position XYZ (12B) | Trunk Scale (4B) | Height Scale (4B) | Canopy Type (2B) | Wind Parameters (2B) | Foliage Seed (4B) Procedural wind swaying calculations driven directly by frequency and phase coefficients

3. Procedural Wind Animation & Frustum Culling Pipeline Diagram

During the rendering pass, the forest subsystem culls tree clusters and animates foliage branches using wind math:

IGI 2 FOREST — PROCEDURAL WIND & CANOPY RENDER PIPELINE 1. CLUSTER CULL • Test Cluster AABB • Frustum Culling Check • Cull Invisible Hills 2. DISTANCE LOD • Dist < 100m: 3D Trunk • Dist > 100m: Crossed Quad • Read 28B Record 3. WIND VERTEX • Sway = sin(Time*F+Ph) • Sway * WindStrength • Procedural Foliage Sway 4. CANOPY RENDER • Direct3D 8 DrawPrimitive • Batched Alpha Test • Dense Forest Vista

4. C++ Struct Definitions

#pragma pack(push, 1)
struct ForestHeader {
    char     magic[4];       // "FORS"
    uint32_t version;        // 2
    uint32_t tree_count;     // Total tree instances
    uint32_t cluster_count;  // Spatial culling clusters
    float    world_min[3];   // Valley bounding minimum
    float    world_max[3];   // Valley bounding maximum
};
static_assert(sizeof(ForestHeader) == 32, "ForestHeader must be 32 bytes");

// IGI 2 28-Byte Tree Instance Record
struct forest_tree_record_s {
    float    pos[3];         // World coordinate XYZ (12B)
    float    scale_trunk;    // Trunk radius scale (4B)
    float    scale_height;   // Tree vertical height (4B)
    uint16_t canopy_type;    // Tree model template ID (2B)
    uint16_t wind_params;    // Wind swaying frequency & phase (2B)
    uint32_t foliage_seed;   // Procedural branching random seed (4B)
};
static_assert(sizeof(forest_tree_record_s) == 28, "forest_tree_record_s must be 28 bytes");
#pragma pack(pop)