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); }
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)); } }
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; } } }
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)); }
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; } } }
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); } } }
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 } }); }
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); } }
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); } } }
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 }); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); } }
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); }
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) } }); }
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); }
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); }
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); }
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) } } }); }
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); } } }
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); }
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); }
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); } }
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; } } }