Exemplo n.º 1
0
        private MeshData GetOrCreateMeshData(ValveBspFile bsp, GeometryPage page, string matPath, bool cacheVertices = true)
        {
            MaterialGroup matGroup;

            var matDictIndex = MaterialDictionary.GetResourceIndex(bsp, matPath);

            if (!page.MaterialIndices.TryGetValue(matDictIndex, out int matIndex))
            {
                var vmt = ValveMaterialFile.FromProvider(MaterialDictionary.GetResourcePath(bsp, matDictIndex), bsp.PakFile, Program.Resources);

                matGroup = new MaterialGroup(matIndex = page.Materials.Count, cacheVertices)
                {
                    Material = matDictIndex
                };
                page.MaterialIndices.Add(matDictIndex, matIndex);
                page.Materials.Add(matGroup);

                FindMaterialAttributes(vmt, matGroup.MeshData.Attributes);
            }
            else
            {
                matGroup = page.Materials[matIndex];
            }

            return(matGroup.MeshData);
        }
Exemplo n.º 2
0
        public static ValveMaterialFile OpenVmt(ValveBspFile bsp, string name)
        {
            if (!name.StartsWith("materials/"))
            {
                name = $"materials/{name}";
            }
            if (!name.EndsWith(".vmt"))
            {
                name = $"{name}.vmt";
            }
            IResourceProvider provider;

            if (bsp != null && bsp.PakFile.ContainsFile(name))
            {
                provider = bsp.PakFile;
            }
            else if (Program.Loader.ContainsFile(name))
            {
                provider = Program.Loader;
            }
            else
            {
                return(null);
            }

            using (var vmtStream = provider.OpenFile(name))
            {
                return(new ValveMaterialFile(vmtStream));
            }
        }
Exemplo n.º 3
0
        protected override IEnumerable <string> OnFindResourcePaths(ValveBspFile bsp)
        {
            for (var i = 0; i < bsp.TextureStringTable.Length; ++i)
            {
                yield return(bsp.GetTextureString(i));
            }

            for (var i = 0; i < bsp.StaticProps.ModelCount; ++i)
            {
                var modelName = bsp.StaticProps.GetModelName(i);
                var mdl       = StudioModelFile.FromProvider(modelName, bsp.PakFile, Program.Resources);

                if (mdl == null)
                {
                    continue;
                }

                for (var j = 0; j < mdl.MaterialCount; ++j)
                {
                    yield return(mdl.GetMaterialName(j, bsp.PakFile, Program.Resources));
                }
            }

            foreach (var entity in bsp.Entities)
            {
                switch (entity.ClassName)
                {
                case "move_rope":
                case "keyframe_rope":
                    yield return(entity["RopeMaterial"]);

                    break;
                }
            }
        }
Exemplo n.º 4
0
        internal static IEnumerable <PageInfo> GetPageLayout(ValveBspFile bsp, int count, int perPage, string filePrefix, Func <int, int> itemSizeSelect = null)
        {
            if (itemSizeSelect == null)
            {
                itemSizeSelect = DefaultItemSizeSelect;
            }

            var first = 0;
            var size  = 0;
            var index = 0;

            for (var i = 0; i < count; ++i)
            {
                var itemSize = itemSizeSelect(i);

                if (size + itemSize > perPage && size > 0)
                {
                    yield return(CreatePage(bsp, first, i, ref index, filePrefix));

                    size  = 0;
                    first = i;
                }

                size += itemSize;
            }

            yield return(CreatePage(bsp, first, count, ref index, filePrefix));
        }
Exemplo n.º 5
0
        internal Displacement(ValveBspFile bsp, DispInfo dispInfo)
        {
            _bspFile  = bsp;
            _dispInfo = dispInfo;
            _corners  = new Vector3[8];

            _min = IntVector2.Zero;
            _max = new IntVector2(Subdivisions, Subdivisions);

            var face             = bsp.FacesHdr[_dispInfo.MapFace];
            var firstCornerDist2 = float.MaxValue;

            Normal = bsp.Planes[face.PlaneNum].Normal;

            for (var i = 0; i < 4; ++i)
            {
                var vert = bsp.GetVertexFromSurfEdgeId(face.FirstEdge + i);
                _corners[i] = vert;

                var dist2 = (_dispInfo.StartPosition - vert).LengthSquared;
                if (dist2 < firstCornerDist2)
                {
                    _firstCorner     = i;
                    firstCornerDist2 = dist2;
                }
            }
        }
Exemplo n.º 6
0
        protected override IEnumerable <string> OnFindResourcePaths(ValveBspFile bsp)
        {
            var items = Enumerable.Range(0, bsp.StaticProps.ModelCount)
                        .Select(x => bsp.StaticProps.GetModelName(x))
                        .Select(x =>
            {
                var mdl = StudioModelFile.FromProvider(x, bsp.PakFile, Program.Resources);
                if (mdl == null)
                {
                    return(null);
                }
                return(new
                {
                    Path = x,
                    VertexCount = mdl.TotalVertices,
                    FirstMaterialIndex = MaterialDictionary.GetResourceIndex(bsp, mdl.GetMaterialName(0, bsp.PakFile, Program.Resources))
                });
            })
                        .Where(x => x != null)
                        .GroupBy(x => x.FirstMaterialIndex)
                        .OrderByDescending(x => x.Count())
                        .SelectMany(x => x)
                        .ToArray();

            foreach (var item in items)
            {
                yield return(item.Path);

                var index = GetResourceIndex(item.Path);
                if (index == _vertexCounts.Count)
                {
                    _vertexCounts.Add(item.VertexCount);
                }
            }
        }
Exemplo n.º 7
0
        private JToken GetSkyMaterial(ValveBspFile bsp, string skyName)
        {
            var postfixes = new[]
            {
                "ft", "bk", "dn", "up", "rt", "lf"
            };

            var propArray = new JArray();
            var faceUrls  = new string[6];

            var i = 0;

            foreach (var postfix in postfixes)
            {
                var matName     = $"materials/skybox/{skyName}{postfix}.vmt";
                var matDir      = Path.GetDirectoryName(matName);
                var vmt         = VmtUtils.OpenVmt(bsp, matName);
                var shaderProps = vmt[vmt.Shaders.FirstOrDefault()];
                var baseTex     = shaderProps["$hdrcompressedtexture"] ?? shaderProps["$basetexture"];
                faceUrls[i++] = VmtUtils.GetTextureUrl(Request, bsp, baseTex, matDir);
            }

            VmtUtils.AddTextureCubeProperty(propArray, "baseTexture", faceUrls);

            return(new JObject
            {
                { "shader", "Sky" },
                { "properties", propArray }
            });
        }
Exemplo n.º 8
0
        public BspTree(ValveBspFile bsp, int modelIndex)
        {
            _bsp = bsp;
            Info = bsp.Models[modelIndex];

            _headNode = new Node(bsp, Info.HeadNode);
        }
 private void FindResourcePaths(ValveBspFile bsp)
 {
     foreach (var path in OnFindResourcePaths(bsp))
     {
         Add(path);
     }
 }
Exemplo n.º 10
0
    public static IEnumerable <int> GetNodeLeafs(ValveBspFile bsp, BspNode node)
    {
        if (node.ChildA.IsLeaf)
        {
            yield return(node.ChildA.Index);
        }
        else
        {
            foreach (var leaf in GetNodeLeafs(bsp, bsp.Nodes[node.ChildA.Index]))
            {
                yield return(leaf);
            }
        }

        if (node.ChildB.IsLeaf)
        {
            yield return(node.ChildB.Index);
        }
        else
        {
            foreach (var leaf in GetNodeLeafs(bsp, bsp.Nodes[node.ChildB.Index]))
            {
                yield return(leaf);
            }
        }
    }
Exemplo n.º 11
0
 private static PageInfo CreatePage(ValveBspFile bsp, int first, int last, ref int index, string filePrefix)
 {
     return(new PageInfo
     {
         First = first,
         Count = last - first,
         Url = filePrefix != null ? $"/maps/{bsp.Name}{filePrefix}{index++}.json" : null
     });
 }
Exemplo n.º 12
0
        public static Material CreateSkyMaterial(ValveBspFile bsp, string skyName)
        {
            var postfixes = new[]
            {
                "rt", "lf", "bk", "ft", "up", "dn"
            };

            var names = new []
            {
                "PosX", "NegX", "PosY", "NegY", "PosZ", "NegZ"
            };

            var skyMaterial = new Material {
                Shader = "SourceUtils.Shaders.Sky"
            };

            skyMaterial.SetBoolean("cullFace", false);

            var hdrCompressed = false;
            var aspect        = 1f;

            for (var face = 0; face < 6; ++face)
            {
                var matPath = $"materials/skybox/{skyName}{postfixes[face]}.vmt";
                var mat     = Get(bsp, matPath);

                if (mat == null)
                {
                    continue;
                }

                var texProp = mat.Properties.FirstOrDefault(x => x.Name == "hdrcompressedtexture")
                              ?? mat.Properties.First(x => x.Name == "basetexture");

                if (face == 0)
                {
                    hdrCompressed = texProp.Name == "hdrcompressedtexture";

                    var tex = Texture.Get(bsp, TextureController.GetTexturePath((Url)texProp.Value));
                    aspect = tex == null ? 1f : (float)tex.Width / tex.Height;
                }

                skyMaterial.SetTextureUrl($"face{names[face]}", (Url)texProp.Value);
            }

            if (hdrCompressed)
            {
                skyMaterial.SetBoolean("hdrCompressed", true);
            }

            if (aspect != 1f)
            {
                skyMaterial.SetNumber("aspect", aspect);
            }

            return(skyMaterial);
        }
Exemplo n.º 13
0
        private static Vector2 GetLightmapUv(ValveBspFile bsp, int x, int y, int dispSize, int faceIndex, ref Face face)
        {
            var lightmapUv = new Vector2((float)x / dispSize, (float)y / dispSize);

            Vector2 min, size;

            bsp.LightmapLayout.GetUvs(faceIndex, out min, out size);

            return(lightmapUv * size + min);
        }
Exemplo n.º 14
0
            public Node(ValveBspFile bsp, int index)
            {
                Index = index;
                Info  = bsp.Nodes[index];

                Plane = bsp.Planes[Info.PlaneNum];

                ChildA = Info.ChildA.IsLeaf ? (IElem) new Leaf(bsp, Info.ChildA.Index) : new Node(bsp, Info.ChildA.Index);
                ChildB = Info.ChildB.IsLeaf ? (IElem) new Leaf(bsp, Info.ChildB.Index) : new Node(bsp, Info.ChildB.Index);
            }
Exemplo n.º 15
0
            public MapParams(ValveBspFile bsp)
            {
                Bsp  = bsp;
                Tree = new BspTree(bsp, 0);

                AreaPortalNames =
                    new HashSet <string>(bsp.Entities
                                         .Where(x => x["classname"] == "func_areaportal")
                                         .Select(x => (string)x["target"])
                                         .Where(x => x != null));
            }
Exemplo n.º 16
0
 public BspToUnity(BspToUnityOptions options)
 {
     if (options.FilePath.StartsWith("sa://", StringComparison.InvariantCultureIgnoreCase))
     {
         options.FilePath = Path.Combine(Application.streamingAssetsPath, options.FilePath.Remove(0, 5));
     }
     if (!options.FilePath.EndsWith(".bsp"))
     {
         options.FilePath = options.FilePath + ".bsp";
     }
     Options = options;
     _bsp    = new ValveBspFile(options.FilePath);
 }
Exemplo n.º 17
0
        public static ValveBspFile GetMap(string name)
        {
            ValveBspFile map;

            if (_sOpenMaps.TryGetValue(name, out map))
            {
                return(map);
            }

            map = new ValveBspFile(Path.Combine(BaseOptions.MapsDir, $"{name}.bsp"));
            _sOpenMaps.Add(name, map);

            return(map);
        }
Exemplo n.º 18
0
        private BspNode ConvertNode(ValveBspFile bsp, int index)
        {
            var node     = bsp.Nodes[index];
            var response = new BspNode
            {
                Min   = node.Min,
                Max   = node.Max,
                Plane = bsp.Planes[node.PlaneNum]
            };

            response.Children[0] = ConvertElement(bsp, node.ChildA);
            response.Children[1] = ConvertElement(bsp, node.ChildB);

            return(response);
        }
Exemplo n.º 19
0
        private static void SerializeDisplacement(ValveBspFile bsp, int faceIndex, ref Face face, ref Plane plane,
                                                  VertexArray verts)
        {
            if (face.NumEdges != 4)
            {
                throw new Exception("Expected displacement to have 4 edges.");
            }

            var disp    = bsp.DisplacementManager[face.DispInfo];
            var texInfo = bsp.TextureInfos[face.TexInfo];

            var texData  = bsp.TextureData[texInfo.TexData];
            var texScale = new Vector2(1f / texData.Width, 1f / texData.Height);

            Vector3 c0, c1, c2, c3;

            disp.GetCorners(out c0, out c1, out c2, out c3);

            var uv00 = GetUv(c0, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
            var uv10 = GetUv(c3, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
            var uv01 = GetUv(c1, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
            var uv11 = GetUv(c2, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;

            for (var y = 0; y < disp.Subdivisions; ++y)
            {
                verts.BeginPrimitive();
                var v0 = (y + 0) / (float)disp.Subdivisions;
                var v1 = (y + 1) / (float)disp.Subdivisions;

                for (var x = 0; x < disp.Size; ++x)
                {
                    var u = x / (float)disp.Subdivisions;

                    var p0 = disp.GetPosition(x, y + 0);
                    var p1 = disp.GetPosition(x, y + 1);

                    var uv0 = (uv00 * (1f - u) + uv10 * u) * (1f - v0) + (uv01 * (1f - u) + uv11 * u) * v0;
                    var uv1 = (uv00 * (1f - u) + uv10 * u) * (1f - v1) + (uv01 * (1f - u) + uv11 * u) * v1;

                    verts.AddVertex(p0, texCoord: uv0, alpha: disp.GetAlpha(x, y + 0) / 255f,
                                    lightmapCoord: GetLightmapUv(bsp, x, y + 0, disp.Subdivisions, faceIndex, ref face));
                    verts.AddVertex(p1, texCoord: uv1, alpha: disp.GetAlpha(x, y + 1) / 255f,
                                    lightmapCoord: GetLightmapUv(bsp, x, y + 1, disp.Subdivisions, faceIndex, ref face));
                }

                verts.CommitPrimitive(PrimitiveType.TriangleStrip, texData.NameStringTableId);
            }
        }
Exemplo n.º 20
0
        public static Material Get(ValveBspFile bsp, string path)
        {
            var vmt = bsp == null
                ? ValveMaterialFile.FromProvider(path, Program.Resources)
                : ValveMaterialFile.FromProvider(path, bsp.PakFile, Program.Resources);

            if (vmt == null)
            {
                return(null);
            }

            var mat = new Material();

            AddMaterialProperties(mat, vmt, path, bsp);

            return(mat);
        }
Exemplo n.º 21
0
        private JToken SerializeFuncBrush(ValveBspFile bsp, BspTree tree, FuncBrush ent)
        {
            var modelIndex = int.Parse(ent.Model.Substring(1));
            var model      = bsp.Models[modelIndex];

            var min = model.Min + ent.Origin;
            var max = model.Max + ent.Origin;

            return(new JObject
            {
                { "classname", ent.ClassName },
                { "origin", ent.Origin.ToJson() },
                { "angles", ent.Angles.ToJson() },
                { "model", modelIndex },
                { "clusters", modelIndex == 0 ? new JArray() : GetIntersectingClusters(tree, min, max) }
            });
        }
Exemplo n.º 22
0
        protected static TDictionary GetDictionary(ValveBspFile bsp)
        {
            TDictionary dict;

            if (_sDicts.TryGetValue(bsp, out dict))
            {
                return(dict);
            }

            dict = new TDictionary();
            dict.FindResourcePaths(bsp);

            bsp.Disposing += _ => _sDicts.Remove(bsp);

            _sDicts.Add(bsp, dict);

            return(dict);
        }
Exemplo n.º 23
0
        public static string GetTextureUrl(HttpListenerRequest request, ValveBspFile bsp, string filePath, string vmtDir)
        {
            filePath = filePath.Replace('\\', '/');

            foreach (var variant in GetTexturePathVariants(filePath, vmtDir))
            {
                if (bsp != null && bsp.PakFile.ContainsFile(variant))
                {
                    return(VtfController.GetUrl(request, variant, bsp.Name));
                }
                if (Program.Loader.ContainsFile(variant))
                {
                    return(VtfController.GetUrl(request, variant));
                }
            }

            return(null);
        }
Exemplo n.º 24
0
        private BspLeaf ConvertLeaf(ValveBspFile bsp, int index)
        {
            var leaf     = bsp.Leaves[index];
            var response = new BspLeaf
            {
                Index    = index,
                Min      = leaf.Min,
                Max      = leaf.Max,
                Flags    = leaf.AreaFlags.Flags,
                HasFaces = leaf.NumLeafFaces > 0
            };

            if (leaf.Cluster != -1)
            {
                response.Cluster = leaf.Cluster;
            }

            return(response);
        }
Exemplo n.º 25
0
        private static JToken SerializeBspNode(ValveBspFile bsp, int index)
        {
            var node  = bsp.Nodes[index];
            var plane = bsp.Planes[node.PlaneNum];

            return(new JObject
            {
                { "plane", plane.ToJson() },
                { "min", node.Min.ToJson() },
                { "max", node.Max.ToJson() },
                {
                    "children", new JArray
                    {
                        SerializeBspChild(bsp, node.ChildA),
                        SerializeBspChild(bsp, node.ChildB)
                    }
                }
            });
        }
Exemplo n.º 26
0
        private static void GetDisplacementBounds(ValveBspFile bsp, int index,
                                                  out SourceUtils.Vector3 min, out SourceUtils.Vector3 max, float bias = 0f)
        {
            min = new SourceUtils.Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
            max = new SourceUtils.Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);

            var disp    = bsp.DisplacementManager[index];
            var biasVec = disp.Normal * bias;

            for (var y = 0; y < disp.Size; ++y)
            {
                for (var x = 0; x < disp.Size; ++x)
                {
                    var pos = disp.GetPosition(x, y);

                    AddToBounds(ref min, ref max, pos - biasVec);
                    AddToBounds(ref min, ref max, pos + biasVec);
                }
            }
        }
Exemplo n.º 27
0
        public static JToken SerializeBspLeaf(ValveBspFile bsp, int index)
        {
            var leaf = bsp.Leaves[index];

            var response = new JObject
            {
                { "index", index },
                { "min", leaf.Min.ToJson() },
                { "max", leaf.Max.ToJson() },
                { "area", leaf.AreaFlags.Area },
                { "flags", (int)leaf.AreaFlags.Flags },
                { "hasFaces", leaf.NumLeafFaces > 0 }
            };

            if (leaf.Cluster != -1)
            {
                response.Add("cluster", leaf.Cluster);
            }

            return(response);
        }
Exemplo n.º 28
0
        private static Vector2 GetLightmapUv(ValveBspFile bsp, Vector3 pos, int faceIndex, ref Face face,
                                             ref TextureInfo texInfo)
        {
            var lightmapUv = GetUv(pos, texInfo.LightmapUAxis, texInfo.LightmapVAxis);

            Vector2 min, size;

            bsp.LightmapLayout.GetUvs(faceIndex, out min, out size);

            lightmapUv.X -= face.LightMapOffsetX - .5f;
            lightmapUv.Y -= face.LightMapOffsetY - .5f;
            lightmapUv.X /= face.LightMapSizeX + 1f;
            lightmapUv.Y /= face.LightMapSizeY + 1f;

            lightmapUv.X *= size.X;
            lightmapUv.Y *= size.Y;
            lightmapUv.X += min.X;
            lightmapUv.Y += min.Y;

            return(lightmapUv);
        }
Exemplo n.º 29
0
        public static ValveBspFile GetBspFile(HttpListenerRequest request, string mapName)
        {
            lock ( _sBspCache )
            {
                ValveBspFile bsp;
                if (_sBspCache.TryGetValue(mapName, out bsp))
                {
                    return(bsp);
                }

                var path = GetMapPath(mapName);
                if (!File.Exists(path))
                {
                    throw new ControllerActionException(request, true, HttpStatusCode.NotFound,
                                                        "The requested resource was not found.");
                }

                bsp = new ValveBspFile(path, mapName);
                _sBspCache.Add(mapName, bsp);

                return(bsp);
            }
        }
Exemplo n.º 30
0
            public IEnumerable <int> GetFaceIndices(ValveBspFile bsp)
            {
                switch (Type)
                {
                case FacesType.Leaf:
                {
                    var leaf = bsp.Leaves[Index];
                    for (int i = leaf.FirstLeafFace, iEnd = leaf.FirstLeafFace + leaf.NumLeafFaces; i < iEnd; ++i)
                    {
                        yield return(bsp.LeafFaces[i]);
                    }

                    yield break;
                }

                case FacesType.Displacement:
                {
                    yield return(bsp.DisplacementInfos[Index].MapFace);

                    yield break;
                }
                }
            }