public BspModelPage GetPage([Url] string map, [Url] int index) { var bsp = Program.GetMap(map); var info = IndexController.GetPageLayout(bsp, bsp.Models.Length, BspModelPage.FacesPerPage, null, i => bsp.Models[i].NumFaces).Skip(index).FirstOrDefault(); var first = info?.First ?? StudioModelDictionary.GetResourceCount(bsp); var count = info?.Count ?? 0; var page = new BspModelPage(); for (var i = first; i < first + count; ++i) { var model = bsp.Models[i]; page.Models.Add(new BspModel { Index = index, Min = model.Min, Max = model.Max, Origin = model.Origin, HeadNode = ConvertNode(bsp, model.HeadNode) }); } 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); }
public Map GetIndexJson([Url] string map) { var bsp = Program.GetMap(map); var ents = new List <Entity>(); var mapParams = new MapParams(bsp); foreach (var ent in bsp.Entities) { var inst = InitEntity(ent, mapParams); if (inst != null) { ents.Add(inst); } } for (var dispIndex = 0; dispIndex < bsp.DisplacementInfos.Length; ++dispIndex) { SourceUtils.Vector3 min, max; GetDisplacementBounds(bsp, dispIndex, out min, out max, 1f); ents.Add(new Displacement { ClassName = "displacement", Index = dispIndex, Clusters = GetIntersectingClusters(mapParams.Tree, min, max) }); } for (var propIndex = 0; propIndex < bsp.StaticProps.PropCount; ++propIndex) { SourceUtils.Vector3 origin, angles; bsp.StaticProps.GetPropTransform(propIndex, out origin, out angles); StaticPropFlags flags; bool solid; uint diffuseMod; bsp.StaticProps.GetPropInfo(propIndex, out flags, out solid, out diffuseMod); int propModelIndex, skin; bsp.StaticProps.GetPropModelSkin(propIndex, out propModelIndex, out skin); var modelName = bsp.StaticProps.GetModelName(propModelIndex); var modelIndex = StudioModelDictionary.GetResourceIndex(bsp, modelName); ents.Add(new StaticProp { ClassName = "prop_static", Origin = origin, Angles = angles, Flags = flags, Clusters = bsp.StaticProps.GetPropLeaves(propIndex) .Select(x => (int)bsp.Leaves[x].Cluster) .Where(x => x != -1) .Distinct(), Model = modelIndex, VertLighting = (flags & StaticPropFlags.NoPerVertexLighting) == 0 ? (int?)propIndex : null, LightingOrigin = (flags & StaticPropFlags.UseLightingOrigin) == 0 ? null : (Vector3?)bsp.StaticProps.GetLightingOrigin(propIndex), AlbedoModulation = diffuseMod != 0xffffffff ? (uint?)diffuseMod : null }); } return(new Map { Name = bsp.Name, LightmapUrl = $"/maps/{bsp.Name}/lightmap.json", VisPages = GetPageLayout(bsp, bsp.Visibility.NumClusters, VisPage.ClustersPerPage, "/geom/vispage"), AmbientPages = GetPageLayout(bsp, bsp.Leaves.Length, AmbientPage.LeavesPerPage, "/geom/ambientpage"), LeafPages = GetPageLayout(bsp, bsp.Leaves.Length, LeafGeometryPage.LeavesPerPage, "/geom/leafpage"), DispPages = GetPageLayout(bsp, bsp.DisplacementInfos.Length, DispGeometryPage.DisplacementsPerPage, "/geom/disppage"), MaterialPages = GetPageLayout(bsp, MaterialDictionary.GetResourceCount(bsp), MaterialPage.MaterialsPerPage, "/materials/matpage"), BrushModelPages = GetPageLayout(bsp, bsp.Models.Length, BspModelPage.FacesPerPage, "/geom/bsppage", i => bsp.Models[i].NumFaces), StudioModelPages = GetPageLayout(bsp, StudioModelDictionary.GetResourceCount(bsp), StudioModelPage.VerticesPerPage, "/geom/mdlpage", i => StudioModelDictionary.GetVertexCount(bsp, i)), VertexLightingPages = GetPageLayout(bsp, bsp.StaticProps.PropCount, VertexLightingPage.PropsPerPage, "/geom/vhvpage"), Entities = ents }); }