Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 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);
        }