|
| 1 | +//! Environment asset definition |
| 2 | +
|
| 3 | +use ltk_mesh::mem::{IndexBuffer, VertexBuffer}; |
| 4 | + |
| 5 | +use crate::{BucketedGeometry, EnvironmentMesh, PlanarReflector, ShaderTextureOverride}; |
| 6 | + |
| 7 | +/// An environment asset contains all geometry data for a League of Legends map. |
| 8 | +/// |
| 9 | +/// This is the primary type for working with `.mapgeo` files. It contains: |
| 10 | +/// - Environment meshes (renderable geometry) |
| 11 | +/// - Shared vertex and index buffers |
| 12 | +/// - Bucketed geometry for spatial queries |
| 13 | +/// - Planar reflectors for reflection rendering |
| 14 | +/// |
| 15 | +/// # Buffer Sharing |
| 16 | +/// |
| 17 | +/// Multiple meshes can reference the same vertex/index buffers. The asset owns |
| 18 | +/// all buffers, and meshes store indices into these buffer arrays. |
| 19 | +/// |
| 20 | +/// # Example |
| 21 | +/// |
| 22 | +/// ```ignore |
| 23 | +/// use ltk_mapgeo::EnvironmentAsset; |
| 24 | +/// use std::fs::File; |
| 25 | +/// |
| 26 | +/// let mut file = File::open("base.mapgeo")?; |
| 27 | +/// let asset = EnvironmentAsset::from_reader(&mut file)?; |
| 28 | +/// |
| 29 | +/// for mesh in asset.meshes() { |
| 30 | +/// println!("Mesh: {} (material: {})", mesh.name(), mesh.material_name()); |
| 31 | +/// |
| 32 | +/// // Access the mesh's vertex buffer |
| 33 | +/// let vb_id = mesh.vertex_buffer_ids()[0]; |
| 34 | +/// let vertex_buffer = &asset.vertex_buffers()[vb_id]; |
| 35 | +/// println!(" Vertices: {}", vertex_buffer.count()); |
| 36 | +/// } |
| 37 | +/// ``` |
| 38 | +#[derive(Debug)] |
| 39 | +pub struct EnvironmentAsset { |
| 40 | + /// Shader texture overrides (global sampler replacements) |
| 41 | + shader_texture_overrides: Vec<ShaderTextureOverride>, |
| 42 | + |
| 43 | + /// Environment meshes (renderable geometry) |
| 44 | + meshes: Vec<EnvironmentMesh>, |
| 45 | + |
| 46 | + /// Bucketed geometry scene graphs (spatial acceleration) |
| 47 | + scene_graphs: Vec<BucketedGeometry>, |
| 48 | + |
| 49 | + /// Planar reflectors |
| 50 | + planar_reflectors: Vec<PlanarReflector>, |
| 51 | + |
| 52 | + /// Shared vertex buffers (meshes reference by index) |
| 53 | + vertex_buffers: Vec<VertexBuffer>, |
| 54 | + |
| 55 | + /// Shared index buffers (meshes reference by index) |
| 56 | + index_buffers: Vec<IndexBuffer<u16>>, |
| 57 | +} |
| 58 | + |
| 59 | +impl EnvironmentAsset { |
| 60 | + /// Creates a new environment asset builder |
| 61 | + pub(crate) fn builder() -> EnvironmentAssetBuilder { |
| 62 | + EnvironmentAssetBuilder::default() |
| 63 | + } |
| 64 | + |
| 65 | + /// The shader texture overrides |
| 66 | + #[inline] |
| 67 | + pub fn shader_texture_overrides(&self) -> &[ShaderTextureOverride] { |
| 68 | + &self.shader_texture_overrides |
| 69 | + } |
| 70 | + |
| 71 | + /// The environment meshes |
| 72 | + #[inline] |
| 73 | + pub fn meshes(&self) -> &[EnvironmentMesh] { |
| 74 | + &self.meshes |
| 75 | + } |
| 76 | + |
| 77 | + /// The bucketed geometry scene graphs |
| 78 | + #[inline] |
| 79 | + pub fn scene_graphs(&self) -> &[BucketedGeometry] { |
| 80 | + &self.scene_graphs |
| 81 | + } |
| 82 | + |
| 83 | + /// The planar reflectors |
| 84 | + #[inline] |
| 85 | + pub fn planar_reflectors(&self) -> &[PlanarReflector] { |
| 86 | + &self.planar_reflectors |
| 87 | + } |
| 88 | + |
| 89 | + /// The shared vertex buffers |
| 90 | + #[inline] |
| 91 | + pub fn vertex_buffers(&self) -> &[VertexBuffer] { |
| 92 | + &self.vertex_buffers |
| 93 | + } |
| 94 | + |
| 95 | + /// The shared index buffers |
| 96 | + #[inline] |
| 97 | + pub fn index_buffers(&self) -> &[IndexBuffer<u16>] { |
| 98 | + &self.index_buffers |
| 99 | + } |
| 100 | + |
| 101 | + /// Gets a vertex buffer by index |
| 102 | + #[inline] |
| 103 | + pub fn vertex_buffer(&self, index: usize) -> Option<&VertexBuffer> { |
| 104 | + self.vertex_buffers.get(index) |
| 105 | + } |
| 106 | + |
| 107 | + /// Gets an index buffer by index |
| 108 | + #[inline] |
| 109 | + pub fn index_buffer(&self, index: usize) -> Option<&IndexBuffer<u16>> { |
| 110 | + self.index_buffers.get(index) |
| 111 | + } |
| 112 | + |
| 113 | + /// Returns the total number of meshes |
| 114 | + #[inline] |
| 115 | + pub fn mesh_count(&self) -> usize { |
| 116 | + self.meshes.len() |
| 117 | + } |
| 118 | + |
| 119 | + /// Returns the total number of vertex buffers |
| 120 | + #[inline] |
| 121 | + pub fn vertex_buffer_count(&self) -> usize { |
| 122 | + self.vertex_buffers.len() |
| 123 | + } |
| 124 | + |
| 125 | + /// Returns the total number of index buffers |
| 126 | + #[inline] |
| 127 | + pub fn index_buffer_count(&self) -> usize { |
| 128 | + self.index_buffers.len() |
| 129 | + } |
| 130 | + |
| 131 | + /// Finds a mesh by name |
| 132 | + pub fn find_mesh(&self, name: &str) -> Option<&EnvironmentMesh> { |
| 133 | + self.meshes.iter().find(|m| m.name() == name) |
| 134 | + } |
| 135 | + |
| 136 | + /// Iterates over meshes with their vertex and index buffers |
| 137 | + pub fn meshes_with_buffers( |
| 138 | + &self, |
| 139 | + ) -> impl Iterator<Item = (&EnvironmentMesh, Vec<&VertexBuffer>, &IndexBuffer<u16>)> { |
| 140 | + self.meshes.iter().filter_map(|mesh| { |
| 141 | + let vertex_buffers: Vec<_> = mesh |
| 142 | + .vertex_buffer_ids() |
| 143 | + .iter() |
| 144 | + .filter_map(|&id| self.vertex_buffers.get(id)) |
| 145 | + .collect(); |
| 146 | + |
| 147 | + let index_buffer = self.index_buffers.get(mesh.index_buffer_id())?; |
| 148 | + |
| 149 | + Some((mesh, vertex_buffers, index_buffer)) |
| 150 | + }) |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +/// Builder for constructing [`EnvironmentAsset`] instances |
| 155 | +#[derive(Default)] |
| 156 | +pub(crate) struct EnvironmentAssetBuilder { |
| 157 | + shader_texture_overrides: Vec<ShaderTextureOverride>, |
| 158 | + meshes: Vec<EnvironmentMesh>, |
| 159 | + scene_graphs: Vec<BucketedGeometry>, |
| 160 | + planar_reflectors: Vec<PlanarReflector>, |
| 161 | + vertex_buffers: Vec<VertexBuffer>, |
| 162 | + index_buffers: Vec<IndexBuffer<u16>>, |
| 163 | +} |
| 164 | + |
| 165 | +impl EnvironmentAssetBuilder { |
| 166 | + pub fn shader_texture_overrides(mut self, overrides: Vec<ShaderTextureOverride>) -> Self { |
| 167 | + self.shader_texture_overrides = overrides; |
| 168 | + self |
| 169 | + } |
| 170 | + |
| 171 | + pub fn meshes(mut self, meshes: Vec<EnvironmentMesh>) -> Self { |
| 172 | + self.meshes = meshes; |
| 173 | + self |
| 174 | + } |
| 175 | + |
| 176 | + pub fn scene_graphs(mut self, scene_graphs: Vec<BucketedGeometry>) -> Self { |
| 177 | + self.scene_graphs = scene_graphs; |
| 178 | + self |
| 179 | + } |
| 180 | + |
| 181 | + pub fn planar_reflectors(mut self, reflectors: Vec<PlanarReflector>) -> Self { |
| 182 | + self.planar_reflectors = reflectors; |
| 183 | + self |
| 184 | + } |
| 185 | + |
| 186 | + pub fn vertex_buffers(mut self, buffers: Vec<VertexBuffer>) -> Self { |
| 187 | + self.vertex_buffers = buffers; |
| 188 | + self |
| 189 | + } |
| 190 | + |
| 191 | + pub fn index_buffers(mut self, buffers: Vec<IndexBuffer<u16>>) -> Self { |
| 192 | + self.index_buffers = buffers; |
| 193 | + self |
| 194 | + } |
| 195 | + |
| 196 | + pub fn build(self) -> EnvironmentAsset { |
| 197 | + EnvironmentAsset { |
| 198 | + shader_texture_overrides: self.shader_texture_overrides, |
| 199 | + meshes: self.meshes, |
| 200 | + scene_graphs: self.scene_graphs, |
| 201 | + planar_reflectors: self.planar_reflectors, |
| 202 | + vertex_buffers: self.vertex_buffers, |
| 203 | + index_buffers: self.index_buffers, |
| 204 | + } |
| 205 | + } |
| 206 | +} |
0 commit comments