public VertexLightingPage GetVertexLightingPage([Url] string map, [Url] int index) { var bsp = Program.GetMap(map); var info = IndexController.GetPageLayout(bsp, bsp.StaticProps.PropCount, VertexLightingPage.PropsPerPage, null).Skip(index).FirstOrDefault(); var first = info?.First ?? bsp.StaticProps.PropCount; var count = info?.Count ?? 0; var page = new VertexLightingPage(); for (var i = 0; i < count; ++i) { var propIndex = first + i; StaticPropFlags flags; bsp.StaticProps.GetPropInfo(propIndex, out flags, out bool _, out uint _); if ((flags & StaticPropFlags.NoPerVertexLighting) != 0) { page.Props.Add(null); continue; } var ldrPath = $"sp_{propIndex}.vhv"; var hdrPath = $"sp_hdr_{propIndex}.vhv"; var existingPath = bsp.PakFile.ContainsFile(hdrPath) ? hdrPath : bsp.PakFile.ContainsFile(ldrPath) ? ldrPath : null; if (existingPath == null) { page.Props.Add(null); continue; } var vhvFile = ValveVertexLightingFile.FromProvider(existingPath, bsp.PakFile); if (vhvFile == null) { page.Props.Add(null); continue; } var meshList = new List <CompressedList <uint> >(); var meshCount = vhvFile.GetMeshCount(0); for (var j = 0; j < meshCount; ++j) { var vertices = new CompressedList <uint>(); var samples = vhvFile.GetSamples(0, j); vertices.AddRange(samples.Select(x => ((uint)x.A << 24) | ((uint)x.B << 16) | ((uint)x.G << 8) | x.R)); meshList.Add(vertices); } page.Props.Add(meshList); } return(page); }
public StudioModelPage GetStudioModelPage([Url] string map, [Url] int index) { var bsp = Program.GetMap(map); var info = IndexController.GetPageLayout(bsp, StudioModelDictionary.GetResourceCount(bsp), StudioModelPage.VerticesPerPage, null, i => StudioModelDictionary.GetVertexCount(bsp, i)).Skip(index).FirstOrDefault(); var first = info?.First ?? StudioModelDictionary.GetResourceCount(bsp); var count = info?.Count ?? 0; var page = new StudioModelPage(); StudioVertex[] vertices = null; int[] indices = null; for (var i = 0; i < count; ++i) { var mdlPath = StudioModelDictionary.GetResourcePath(bsp, first + i); var vvdPath = mdlPath.Replace(".mdl", ".vvd"); var vtxPath = mdlPath.Replace(".mdl", ".dx90.vtx"); var mdlFile = StudioModelFile.FromProvider(mdlPath, bsp.PakFile, Program.Resources); var vvdFile = ValveVertexFile.FromProvider(vvdPath, bsp.PakFile, Program.Resources); var vtxFile = ValveTriangleFile.FromProvider(vtxPath, mdlFile, vvdFile, bsp.PakFile, Program.Resources); StudioModel mdl; page.Models.Add(mdl = new StudioModel()); for (var j = 0; j < mdlFile.BodyPartCount; ++j) { SmdBodyPart smdBodyPart; mdl.BodyParts.Add(smdBodyPart = new SmdBodyPart { Name = mdlFile.GetBodyPartName(j) }); smdBodyPart.Models.AddRange(mdlFile.GetModels(j).Select((model, modelIndex) => { var smdModel = new SmdModel(); smdModel.Meshes.AddRange(mdlFile.GetMeshes(ref model).Select((mesh, meshIndex) => { var vertexCount = vtxFile.GetVertexCount(j, modelIndex, 0, meshIndex); if (vertices == null || vertices.Length < vertexCount) { vertices = new StudioVertex[MathHelper.NextPowerOfTwo(vertexCount)]; } var indexCount = vtxFile.GetIndexCount(j, modelIndex, 0, meshIndex); if (indices == null || indices.Length < indexCount) { indices = new int[MathHelper.NextPowerOfTwo(indexCount)]; } vtxFile.GetVertices(j, modelIndex, 0, meshIndex, vertices); vtxFile.GetIndices(j, modelIndex, 0, meshIndex, indices); var meshData = GetOrCreateMeshData(bsp, page, mdlFile.GetMaterialName(mesh.Material, bsp.PakFile, Program.Resources), false); var meshElem = new MeshElement { Mode = PrimitiveType.Triangles, IndexOffset = meshData.Indices.Count, VertexOffset = meshData.Vertices.Count }; var smdMesh = new SmdMesh { MeshId = mesh.MeshId, Material = meshData.MaterialIndex, Element = meshData.Elements.Count }; meshData.BeginPrimitive(); for (var k = 0; k < vertexCount; ++k) { var vertex = vertices[k]; meshData.VertexAttribute(VertexAttribute.Position, vertex.Position); meshData.VertexAttribute(VertexAttribute.Normal, vertex.Normal); meshData.VertexAttribute(VertexAttribute.Uv, new Vector2(vertex.TexCoordX, vertex.TexCoordY)); meshData.CommitVertex(); } meshData.CommitPrimitive(PrimitiveType.Triangles, indices.Take(indexCount)); meshElem.IndexCount = meshData.Indices.Count - meshElem.IndexOffset; meshElem.VertexCount = meshData.Vertices.Count - meshElem.VertexOffset; meshData.Elements.Add(meshElem); return(smdMesh); })); return(smdModel); })); } } return(page); }