示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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
            });
        }