public IGeometryModel ReadGeometry(int lod) { if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount) { throw new ArgumentOutOfRangeException(nameof(lod)); } using (var reader = cache.CreateReader(cache.DefaultAddressTranslator)) { var model = new GeometryModel(item.FileName()) { CoordinateSystem = CoordinateSystem.Default }; var shaderRefs = Lightmaps.SelectMany(m => m.Materials) .Where(m => m.ShaderReference.TagId >= 0) .GroupBy(m => m.ShaderReference.TagId) .Select(g => g.First().ShaderReference) .ToList(); var shaderIds = shaderRefs.Select(r => r.TagId).ToList(); model.Materials.AddRange(Halo1Common.GetMaterials(shaderRefs, reader)); reader.Seek(SurfacePointer.Address, SeekOrigin.Begin); var indices = reader.ReadEnumerable <ushort>(SurfaceCount * 3).ToArray(); var gRegion = new GeometryRegion { Name = "Clusters" }; int sectionIndex = 0; foreach (var section in Lightmaps) { if (section.Materials.Count == 0) { continue; } var localIndices = new List <int>(); var vertices = new List <WorldVertex>(); var submeshes = new List <IGeometrySubmesh>(); var gPermutation = new GeometryPermutation { SourceIndex = Lightmaps.IndexOf(section), Name = sectionIndex.ToString("D3", CultureInfo.CurrentCulture), MeshIndex = sectionIndex, MeshCount = 1 }; foreach (var submesh in section.Materials) { reader.Seek(submesh.VertexPointer.Address, SeekOrigin.Begin); submeshes.Add(new GeometrySubmesh { MaterialIndex = (short)shaderIds.IndexOf(submesh.ShaderReference.TagId), IndexStart = localIndices.Count, IndexLength = submesh.SurfaceCount * 3 }); localIndices.AddRange( indices.Skip(submesh.SurfaceIndex * 3) .Take(submesh.SurfaceCount * 3) .Select(i => i + vertices.Count) ); var vertsTemp = reader.ReadEnumerable <WorldVertex>(submesh.VertexCount).ToList(); vertices.AddRange(vertsTemp); } gRegion.Permutations.Add(gPermutation); model.Meshes.Add(new GeometryMesh { IndexFormat = IndexFormat.TriangleList, VertexWeights = VertexWeights.None, Indicies = localIndices.ToArray(), Vertices = vertices.ToArray(), Submeshes = submeshes }); sectionIndex++; } model.Regions.Add(gRegion); return(model); } }