-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Feature: Map Geometry (.mapgeo) Parser and Builder
Summary
Implement a Rust parser and builder for Map Geometry environment files (.mapgeo), which contain 3D geometry data for League of Legends maps.
Reference Implementation
C# LeagueToolkit: https://github.com/LeagueToolkit/LeagueToolkit/blob/main/src/LeagueToolkit/Core/Environment/EnvironmentAsset.cs
Related types in the same repository:
EnvironmentAssetMesh.cs- Mesh dataEnvironmentAssetShaderTextureOverride.cs- Shader overridesBucketedGeometry.cs- Spatial scene graphGeometryBucket.cs- Individual bucket cellsPlanarReflector.cs- Reflection planes
Format Overview
- Magic:
OEGM - Versions: 5, 6, 7, 9, 11, 12, 13, 14, 15, 17
- Contents: Vertex/index buffers, meshes, spatial bucketing, planar reflectors
Understanding Bucketed Geometry
The mapgeo format contains two separate geometry systems:
1. Environment Meshes - Renderable Geometry
- Full vertex data (positions, normals, UVs, colors, tangents)
- Material references and textures
- Used for actual GPU rendering
- Each mesh has its own bounding box/sphere for frustum culling
2. Bucketed Geometry - Spatial Query Geometry
- Simplified vertices (positions only) and indices
- No materials or vertex attributes
- Used for spatial queries, not rendering
How Bucketing Works
The map is divided into a uniform 2D grid on the XZ plane (top-down). Each cell (bucket) contains:
┌─────┬─────┬─────┬─────┐
│ 0,3 │ 1,3 │ 2,3 │ 3,3 │ ← Top-down view of map
├─────┼─────┼─────┼─────┤
│ 0,2 │ 1,2 │ 2,2 │ 3,2 │
├─────┼─────┼─────┼─────┤
│ 0,1 │ 1,1 │ 2,1 │ 3,1 │ Each cell is a "bucket"
├─────┼─────┼─────┼─────┤
│ 0,0 │ 1,0 │ 2,0 │ 3,0 │
└─────┴─────┴─────┴─────┘
Each GeometryBucket stores:
StartIndex/BaseVertex- Range into shared vertex/index buffersInsideFaceCount- Triangles fully contained in bucketStickingOutFaceCount- Triangles extending beyond bucket boundsMaxStickOutX/Z- How far geometry extends (expands culling bounds)
Purpose of Bucketed Geometry
The bucketed data serves as a low-detail spatial acceleration structure for:
- CPU-side occlusion culling - Simplified proxy geometry for visibility queries
- Collision / Raycasting - Fast spatial queries without full mesh detail
- Visibility layer control - Per-face
EnvironmentVisibilityflags for fog of war or layer-based visibility
Relationship Between Systems
Notably, there are no explicit references from buckets to meshes in the file format. The systems are independent:
- Meshes self-cull using their bounding volumes against the camera frustum
- Buckets provide acceleration for collision, occlusion, and visibility queries
- The game engine likely builds mesh↔bucket associations at runtime based on spatial overlap
The VisibilityControllerPathHash in BucketedGeometry suggests integration with a visibility controller system for fog of war or area-based effects.
Existing Infrastructure
The codebase already has building blocks to leverage:
ltk_file- RecognizesMapGeometrykind and OEGM magicltk_mesh::mem-VertexBuffer,IndexBuffer,VertexBufferDescriptiontypesltk_primitives-AABB,Sphere,Color
Rust-Specific Improvements
Consider the following improvements over the C# implementation:
Data Representation
- Zero-copy buffer access - Use memory-mapped views or
Cow<[u8]>for vertex/index data to avoid unnecessary allocations when only reading - Typed vertex accessors - Provide strongly-typed iterators over vertex attributes (positions, normals, UVs) instead of raw byte access
- Arena-based mesh references - Use indices or handles to reference shared buffers rather than
Rc/Arcto keep data cache-friendly
Ergonomics
- Builder pattern - Provide
EnvironmentAssetBuilderwith validation at construction time - Mesh iteration - Implement
IntoIteratorfor convenient mesh traversal - Submesh slicing - Allow extracting submesh geometry as standalone views
Integration
- glTF export - Consider optional conversion to glTF for interoperability with 3D tools
- Spatial queries - Expose bucketed geometry for efficient ray-casting or frustum culling
- Mesh merging - Utility to merge meshes sharing materials for rendering optimization
Performance
- Parallel reading - Vertex/index buffers can be read in parallel after parsing headers
- Lazy buffer loading - Defer buffer reads until accessed (useful for large maps)
- SIMD vertex processing - Use
glamSIMD types for batch vertex transformations
Bucketed Geometry API
- Bucket lookup -
get_bucket(world_x, world_z) -> &GeometryBucket - Range queries -
buckets_in_region(aabb) -> impl Iterator<Item = &GeometryBucket> - Raycast support -
raycast(origin, direction) -> Option<RayHit>using bucket acceleration
Tasks
- Implement reading for all supported versions (5-17) #87
- Implement writing (version 17)
- Provide typed access to vertex attributes
- Add spatial query utilities for bucketed geometry
- Round-trip tests with real
.mapgeofiles - Documentation with usage examples
Notes
- Essential for map modding/visualization tools
- File uses little-endian byte order
- Index buffers use
u16indices - Scene graphs use spatial bucketing for efficient culling
- Bucketed geometry is separate from renderable meshes (no direct references)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status