private void ReadFaces(BSPParser bspParser, VPKParser vpkParser, CancellationToken cancelToken, Action <float, string> onProgressChanged = null) { for (int i = 0; i < Mathf.RoundToInt(bspParser.faces.Length * FaceLoadPercent); i++) { if (cancelToken.IsCancellationRequested) { return; } dface_t face = bspParser.faces[i]; texflags currentTexFlags = GetFaceTextureFlags(face, bspParser); string textureLocation = GetFaceTextureLocation(face, bspParser); if (!IsUndesiredTexture(textureLocation, currentTexFlags)) { FaceMesh currentFace = new FaceMesh(); currentFace.textureFlag = currentTexFlags; currentFace.lightmapKey = bspParser.faces[i].lightofs; currentFace.faceName = textureLocation; currentFace.material = VMTData.GrabVMT(bspParser, vpkParser, textureLocation); currentFace.meshData = MakeFace(bspParser, face); AddFaceMesh(currentFace, combineMeshesWithSameTexture); } totalItemsLoaded++; onProgressChanged?.Invoke(PercentLoaded, currentMessage); } }
private void ReadMap() { System.IO.FileStream mapFile = null; try { mapFile = new System.IO.FileStream(mapLocation + mapName + ".bsp", System.IO.FileMode.Open); } catch (Exception e) { Console.WriteLine(e.Message); } if (mapFile != null) { #region Read map BSPParser bsp = new BSPParser(mapFile); string entities = bsp.GetEntities(); //Console.WriteLine("Map Entities: " + entities); vertices = bsp.GetVertices(); edges = bsp.GetEdges(); faces = bsp.GetFaces(); surfedges = bsp.GetSurfedges(); texInfo = bsp.GetTextureInfo(); texData = bsp.GetTextureData(); texStringTable = bsp.GetTextureStringTable(); textureStringData = bsp.GetTextureStringData(); mapFile.Close(); #endregion } }
private void ReadStaticProps(BSPParser bspParser, VPKParser vpkParser, CancellationToken cancelToken, Action <float, string> onProgressChanged = null) { int staticPropCount = Mathf.RoundToInt(bspParser.staticProps.staticPropInfo.Length * ModelLoadPercent); staticProps = new StaticPropData[staticPropCount]; for (int i = 0; i < staticPropCount; i++) { if (cancelToken.IsCancellationRequested) { return; } var currentPropInfo = bspParser.staticProps.staticPropInfo[i]; ushort propType = currentPropInfo.PropType; string modelFullPath = bspParser.staticProps.staticPropDict.names[propType]; modelFullPath = modelFullPath.Substring(0, modelFullPath.LastIndexOf(".")); staticProps[i].model = SourceModel.GrabModel(bspParser, vpkParser, modelFullPath); staticProps[i].debug = currentPropInfo.ToString(); staticProps[i].origin = currentPropInfo.Origin; staticProps[i].angles = currentPropInfo.Angles; totalItemsLoaded++; onProgressChanged?.Invoke(PercentLoaded, currentMessage); } }
private void ReadFile() { bsp = new BSPParser(mapFile); string entities = bsp.GetEntities(); Debug.Log("Map Entities: " + entities); vertices = bsp.GetVertices(); //vertices = bsp.lumpData[3]; //planes = bsp.GetPlanes(); edges = bsp.GetEdges(); //origFaces = bsp.GetOriginalFaces(); faces = bsp.GetFaces(); surfedges = bsp.GetSurfedges(); //brushes = bsp.GetBrushes(); //brushSides = bsp.GetBrushSides(); dispInfo = bsp.GetDispInfo(); dispVerts = bsp.GetDispVerts(); texInfo = bsp.GetTextureInfo(); texData = bsp.GetTextureData(); texStringTable = bsp.GetTextureStringTable(); textureStringData = bsp.GetTextureStringData(); staticProps = bsp.GetStaticProps(); mapFile.Close(); }
private string GetFaceTextureLocation(dface_t face, BSPParser bspParser) { int faceTexInfoIndex = face.texinfo; int texDataIndex = bspParser.texInfo[faceTexInfoIndex].texdata; int nameStringTableIndex = bspParser.texData[texDataIndex].nameStringTableID; return(bspParser.textureStringData[nameStringTableIndex]); }
private texflags GetFaceTextureFlags(dface_t face, BSPParser bspParser) { texflags currentTexFlag = texflags.SURF_SKIP; if (bspParser.texInfo != null && face.texinfo < bspParser.texInfo.Length) { currentTexFlag = (texflags)bspParser.texInfo[face.texinfo].flags; } return(currentTexFlag); }
public static SourceTexture GrabTexture(BSPParser bspParser, VPKParser vpkParser, string rawPath) { SourceTexture srcTexture = null; if (!string.IsNullOrEmpty(rawPath)) { string vtfFilePath = FixLocation(bspParser, vpkParser, rawPath); if (!string.IsNullOrEmpty(vtfFilePath)) { if (loadedTextures.ContainsKey(vtfFilePath)) { srcTexture = loadedTextures[vtfFilePath]; } else { if (bspParser != null && bspParser.HasPakFile(vtfFilePath)) { //Debug.Log("Loaded " + vtfFilePath + " from pakfile"); srcTexture = ReadAndCache(bspParser.GetPakFile(vtfFilePath), vtfFilePath); } else if (vpkParser != null && vpkParser.FileExists(vtfFilePath)) { try { vpkParser.LoadFileAsStream(vtfFilePath, (stream, origOffset, fileLength) => { srcTexture = ReadAndCache(stream, origOffset, vtfFilePath); }); } catch (Exception e) { Debug.LogError("SourceTexture: " + e.ToString()); } } else { Debug.LogError("SourceTexture: Could not find Texture FixedPath(" + vtfFilePath + ") RawPath(" + rawPath + ")"); } } } else { Debug.LogError("SourceTexture: Could not find texture at " + rawPath); } } else { Debug.LogError("SourceTexture: Texture string path is null or empty"); } return(srcTexture); }
void Awake() { parser = new BSPParser(RESOURCESPATH + FILENAME); _textures = parser.Textures; _vertexes = parser.Vertexes; _planes = parser.Planes; _faces = parser.Faces; _models = parser.Models; _meshverts = parser.Meshverts; _nodes = parser.Nodes; _leafs = parser.Leafs; _leaffaces = parser.Leaffaces; _visdata = parser.Visdata; _playerstart = parser.GetPlayerStartPosition(); }
public static string FixLocation(BSPParser bspParser, VPKParser vpkParser, string rawPath) { string fixedLocation = rawPath.Replace("\\", "/").ToLower(); if (!Path.GetExtension(fixedLocation).Equals(".vtf") && (bspParser == null || !bspParser.HasPakFile(fixedLocation)) && (vpkParser == null || !vpkParser.FileExists(fixedLocation))) { fixedLocation += ".vtf"; } if ((bspParser == null || !bspParser.HasPakFile(fixedLocation)) && (vpkParser == null || !vpkParser.FileExists(fixedLocation))) { fixedLocation = Path.Combine("materials", fixedLocation).Replace("\\", "/"); } return(fixedLocation); }
public static SourceModel GrabModel(BSPParser bspParser, VPKParser vpkParser, string rawPath) { SourceModel model = null; string fixedLocation = rawPath.Replace("\\", "/").ToLower(); if (loadedModels.ContainsKey(fixedLocation)) { model = loadedModels[fixedLocation]; } else { model = new SourceModel(fixedLocation); model.Parse(bspParser, vpkParser); } return(model); }
private void GrabDependants(BSPParser bspParser, VPKParser vpkParser) { if (!string.IsNullOrEmpty(includedVmtPath)) { includedVmt = VMTData.GrabVMT(bspParser, vpkParser, includedVmtPath); } if (!string.IsNullOrEmpty(baseTexturePath)) { baseTexture = SourceTexture.GrabTexture(bspParser, vpkParser, baseTexturePath); } if (!string.IsNullOrEmpty(bumpMapPath)) { bumpMap = SourceTexture.GrabTexture(bspParser, vpkParser, bumpMapPath); } if (!string.IsNullOrEmpty(detailMapPath)) { detailMap = SourceTexture.GrabTexture(bspParser, vpkParser, detailMapPath); } }
public void ParseFile(CancellationToken cancelToken, Action <float, string> onProgressChanged = null, Action onFinished = null) { isParsed = false; isParsing = true; //currentMessage = "Reading BSP Data"; //onProgressChanged?.Invoke(PercentLoaded, currentMessage); using (VPKParser vpkParser = new VPKParser(vpkLoc)) using (BSPParser bspParser = new BSPParser(Path.Combine(mapDir, mapName + ".bsp"))) { bspParser.ParseData(cancelToken); //if (!cancelToken.IsCancellationRequested) // lightmaps = bspParser.GetLightmaps(cancelToken); int facesCount = Mathf.RoundToInt(bspParser.faces.Length * FaceLoadPercent); int propsCount = Mathf.RoundToInt(bspParser.staticProps.staticPropInfo.Length * ModelLoadPercent); totalItemsToLoad = facesCount + propsCount; bool validVPK = vpkParser.IsValid(); currentMessage = "Reading Map Faces"; onProgressChanged?.Invoke(PercentLoaded, currentMessage); ReadFaces(bspParser, validVPK ? vpkParser : null, cancelToken, onProgressChanged); currentMessage = "Reading Map Models"; onProgressChanged?.Invoke(PercentLoaded, currentMessage); if (validVPK) { ReadStaticProps(bspParser, vpkParser, cancelToken, onProgressChanged); } } onFinished?.Invoke(); isParsing = false; isParsed = true; }
public static void LoadEntities2(string file) { FileStream fs = File.OpenRead(file); BSPParser p = new BSPParser(fs); if (p.LoadDirectoryTables()) { string entities = p.ReadEntities(); Console.WriteLine(entities); EntityParser ep = new EntityParser(entities); var ent = ep.ReadEntities(); Console.WriteLine(ent["worldspawn"][0]["wad"]); Console.WriteLine(ent["worldspawn"][0]["skyname"]); if (ent.ContainsKey("ambient_generic")) { var sounds = ent["ambient_generic"]; foreach (var sound in sounds) { Console.WriteLine(sound["message"]); } } } }
public static void LoadEntities(string file) { FileStream fs = File.OpenRead(file); BSPParser p = new BSPParser(fs); if (p.LoadDirectoryTables()) { string entities = p.ReadEntities(); EntityParser ep = new EntityParser(entities); foreach (var entity in ep.Entities) { Console.Write("{"); foreach (var kvp in entity) { Console.Write(kvp); Console.Write(","); } Console.WriteLine("}"); } Console.WriteLine(); } }
private void ReadFaceMeshes(MDLParser mdl, VVDParser vvd, VTXParser vtx, BSPParser bspParser, VPKParser vpkParser) { int textureIndex = 0; if (mdl.bodyParts.Length == vtx.bodyParts.Length) { for (int bodyPartIndex = 0; bodyPartIndex < mdl.bodyParts.Length; bodyPartIndex++) { for (int modelIndex = 0; modelIndex < mdl.bodyParts[bodyPartIndex].models.Length; modelIndex++) { //int currentPosition = 0; for (int meshIndex = 0; meshIndex < mdl.bodyParts[bodyPartIndex].models[modelIndex].theMeshes.Length; meshIndex++) { int rootLodIndex = mdl.header1.rootLod; //int rootLodIndex = 0; //int rootLodCount = 1; //if (mdl.header1.numAllowedRootLods == 0) // rootLodCount = vtx.header.numLODs; FaceMesh currentFace = new FaceMesh(); int verticesStartIndex = mdl.bodyParts[bodyPartIndex].models[modelIndex].theMeshes[meshIndex].vertexIndexStart; int vertexCount = 0; //int vertexCount = mdl.bodyParts[bodyPartIndex].models[modelIndex].theMeshes[meshIndex].vertexCount; //int vertexCount = mdl.bodyParts[bodyPartIndex].models[modelIndex].theMeshes[meshIndex].vertexData.lodVertexCount[rootLodIndex]; //int vertexCount = 0; //for (int i = 0; i <= rootLodIndex; i++) // vertexCount += mdl.bodyParts[bodyPartIndex].models[modelIndex].theMeshes[meshIndex].vertexData.lodVertexCount[i]; int trianglesCount = 0; for (int stripGroupIndex = 0; stripGroupIndex < vtx.bodyParts[bodyPartIndex].theVtxModels[modelIndex].theVtxModelLods[rootLodIndex].theVtxMeshes[meshIndex].stripGroupCount; stripGroupIndex++) { var currentStripGroup = vtx.bodyParts[bodyPartIndex].theVtxModels[modelIndex].theVtxModelLods[rootLodIndex].theVtxMeshes[meshIndex].theVtxStripGroups[stripGroupIndex]; for (int stripIndex = 0; stripIndex < currentStripGroup.theVtxStrips.Length; stripIndex++) { var currentStrip = currentStripGroup.theVtxStrips[stripIndex]; if (((StripHeaderFlags_t)currentStrip.flags & StripHeaderFlags_t.STRIP_IS_TRILIST) > 0) { trianglesCount += currentStrip.indexCount; } } } //List<int> triangles = new List<int>(); int[] triangles = new int[trianglesCount]; int trianglesIndex = 0; //for (int countUpLodIndex = 0; countUpLodIndex <= rootLodIndex; countUpLodIndex++) //{ for (int stripGroupIndex = 0; stripGroupIndex < vtx.bodyParts[bodyPartIndex].theVtxModels[modelIndex].theVtxModelLods[rootLodIndex].theVtxMeshes[meshIndex].stripGroupCount; stripGroupIndex++) { //var currentStripGroup = vtx.bodyParts[bodyPartIndex].theVtxModels[modelIndex].theVtxModelLods[rootLodIndex].theVtxMeshes[meshIndex].theVtxStripGroups[0]; var currentStripGroup = vtx.bodyParts[bodyPartIndex].theVtxModels[modelIndex].theVtxModelLods[rootLodIndex].theVtxMeshes[meshIndex].theVtxStripGroups[stripGroupIndex]; //int trianglesCount = currentStripGroup.theVtxIndices.Length; //int[] triangles = new int[trianglesCount]; for (int stripIndex = 0; stripIndex < currentStripGroup.theVtxStrips.Length; stripIndex++) { var currentStrip = currentStripGroup.theVtxStrips[stripIndex]; if (((StripHeaderFlags_t)currentStrip.flags & StripHeaderFlags_t.STRIP_IS_TRILIST) > 0) { for (int indexIndex = 0; indexIndex < currentStrip.indexCount; indexIndex += 3) { int vertexIndexA = verticesStartIndex + currentStripGroup.theVtxVertices[currentStripGroup.theVtxIndices[indexIndex + currentStrip.indexMeshIndex]].originalMeshVertexIndex; int vertexIndexB = verticesStartIndex + currentStripGroup.theVtxVertices[currentStripGroup.theVtxIndices[indexIndex + currentStrip.indexMeshIndex + 2]].originalMeshVertexIndex; int vertexIndexC = verticesStartIndex + currentStripGroup.theVtxVertices[currentStripGroup.theVtxIndices[indexIndex + currentStrip.indexMeshIndex + 1]].originalMeshVertexIndex; vertexCount = Mathf.Max(vertexCount, vertexIndexA, vertexIndexB, vertexIndexC); //if (vertexIndexA < vertices.Length && vertexIndexB < vertices.Length && vertexIndexC < vertices.Length) //{ triangles[trianglesIndex++] = vertexIndexA; triangles[trianglesIndex++] = vertexIndexB; triangles[trianglesIndex++] = vertexIndexC; //triangles.Add(vertexIndexA); //triangles.Add(vertexIndexB); //triangles.Add(vertexIndexC); //} } } } } //} vertexCount += 1; //vertexCount = vvd.vertices.Length; //vertexCount = vvd.header.numLODVertices[rootLodIndex]; Vector3[] vertices = new Vector3[vertexCount]; Vector3[] normals = new Vector3[vertexCount]; Vector2[] uv = new Vector2[vertexCount]; for (int verticesIndex = 0; verticesIndex < vertices.Length; verticesIndex++) { vertices[verticesIndex] = vvd.vertices[verticesIndex].m_vecPosition; normals[verticesIndex] = vvd.vertices[verticesIndex].m_vecNormal; uv[verticesIndex] = vvd.vertices[verticesIndex].m_vecTexCoord; } Debug.Assert(triangles.Length % 3 == 0, "SourceModel: Triangles not a multiple of three for " + modelPath); if (mdl.header1.includemodel_count > 0) { Debug.LogWarning("SourceModel: Include model count greater than zero (" + mdl.header1.includemodel_count + ", " + mdl.header1.includemodel_index + ") for " + modelPath); } if (vvd.header.numFixups > 0) { Debug.LogWarning("SourceModel: " + vvd.header.numFixups + " fixups found for " + modelPath); } MeshHelpers.MeshData meshData; //var outcome = MeshHelpers.GenerateConvexHull(vertices, out meshData, 0.2); //if (outcome != MIConvexHull.ConvexHullCreationResultOutcome.Success) // Debug.LogError("SourceModel: Convex hull error " + outcome + " for " + modelPath); if (decimationPercent > 0) { meshData = MeshHelpers.DecimateByTriangleCount(vertices, triangles, normals, 1 - decimationPercent); meshData.uv = new Vector2[meshData.vertices.Length]; System.Array.Copy(uv, meshData.uv, meshData.vertices.Length); } else { meshData = new MeshHelpers.MeshData(); meshData.vertices = vertices; meshData.triangles = triangles; meshData.normals = normals; meshData.uv = uv; } currentFace.meshData = meshData; string textureName = ""; string texturePath = mdl.texturePaths[0].Replace("\\", "/").ToLower(); if (textureIndex < mdl.textures.Length) { textureName = mdl.textures[textureIndex].name.Replace("\\", "/").ToLower(); } //textureName = mdl.textures[textureIndex].name.Replace("\\", "/").ToLower(); if (textureName.IndexOf(texturePath) > -1) { texturePath = ""; } string textureLocation = texturePath + textureName; //if (modelTextures != null && textureIndex < modelTextures.Length) //Should not have this line // textureLocation = modelTextures[textureIndex]?.location; currentFace.faceName = textureLocation; currentFace.material = VMTData.GrabVMT(bspParser, vpkParser, textureLocation); //if (!excludeTextures) // currentFace.texture = SourceTexture.GrabTexture(bspParser, vpkParser, textureLocation); faces.Add(currentFace); textureIndex++; } } } } else { Debug.LogError("SourceModel: MDL and VTX body part count doesn't match (" + modelPath + ")"); } }
/*public static VMTData GrabVMT(byte[] data, string rawPath) * { * VMTData vmtData = null; * * if (!string.IsNullOrEmpty(rawPath)) * { * string vmtFilePath = rawPath.Replace("\\", "/").ToLower(); * * if (vmtCache.ContainsKey(vmtFilePath)) * { * vmtData = vmtCache[vmtFilePath]; * } * else * { * vmtData = new VMTData(vmtFilePath); * vmtData.Parse(data); * } * } * else * Debug.LogError("VMTData: Given path is null or empty"); * * return vmtData; * }*/ public static VMTData GrabVMT(BSPParser bspParser, VPKParser vpkParser, string rawPath, bool grabDependants = true) { VMTData vmtData = null; if (!string.IsNullOrEmpty(rawPath)) { string vmtFilePath = FixLocation(bspParser, vpkParser, rawPath); if (vmtCache.ContainsKey(vmtFilePath)) { vmtData = vmtCache[vmtFilePath]; if (grabDependants) { vmtData.GrabDependants(bspParser, vpkParser); } } else { if (bspParser != null && bspParser.HasPakFile(vmtFilePath)) { vmtData = new VMTData(vmtFilePath); //Debug.Log("Loaded " + vmtFilePath + " from pakfile"); vmtData.Parse(bspParser.GetPakFile(vmtFilePath)); if (grabDependants) { vmtData.GrabDependants(bspParser, vpkParser); } } else if (vpkParser != null && vpkParser.FileExists(vmtFilePath)) { try { byte[] vmtByteData = null; vpkParser.LoadFileAsStream(vmtFilePath, (stream, origOffset, fileLength) => { vmtByteData = new byte[fileLength]; stream.Position = origOffset; stream.Read(vmtByteData, 0, vmtByteData.Length); }); vmtData = new VMTData(vmtFilePath); vmtData.Parse(vmtByteData); if (grabDependants) { vmtData.GrabDependants(bspParser, vpkParser); } } catch (System.Exception e) { Debug.LogError("VMTData: " + e.ToString()); } } else { string vtfFilePath = SourceTexture.FixLocation(bspParser, vpkParser, rawPath); if ((bspParser != null && bspParser.HasPakFile(vtfFilePath)) || (vpkParser != null && vpkParser.FileExists(vtfFilePath))) { vmtData = new VMTData(vmtFilePath); vmtData.baseTexturePath = rawPath; if (grabDependants) { vmtData.GrabDependants(bspParser, vpkParser); } } else { Debug.LogError("VMTData: Could not find VMT file at FixedPath(" + vmtFilePath + ") RawPath(" + rawPath + ")"); } } } } else { Debug.LogError("VMTData: Given path is null or empty"); } return(vmtData); }
void Awake() { parser = new BSPParser(RESOURCESPATH + FILENAME); _entities = parser.Entities; _textures = parser.Textures; _vertexes = parser.Vertexes; _planes = parser.Planes; _faces = parser.Faces; _models = parser.Models; _meshverts = parser.Meshverts; _nodes = parser.Nodes; _leafs = parser.Leafs; _leaffaces = parser.Leaffaces; _visdata = parser.Visdata; _playerstart = parser.GetPlayerStartPosition(); mesh = new UnityEngine.Mesh(); }
public MeshHelpers.MeshData MakeFace(BSPParser bspParser, dface_t face) { #region Get all vertices of face List <Vector3> surfaceVertices = new List <Vector3>(); List <Vector3> originalVertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); for (int i = 0; i < face.numedges; i++) { ushort[] currentEdge = bspParser.edges[Mathf.Abs(bspParser.surfedges[face.firstedge + i])].v; Vector3 point1 = bspParser.vertices[currentEdge[0]], point2 = bspParser.vertices[currentEdge[1]]; Vector3 planeNormal = bspParser.planes[face.planenum].normal; point1 = new Vector3(point1.x, point1.y, point1.z); point2 = new Vector3(point2.x, point2.y, point2.z); if (bspParser.surfedges[face.firstedge + i] >= 0) { if (surfaceVertices.IndexOf(point1) < 0) { surfaceVertices.Add(point1); normals.Add(planeNormal); } originalVertices.Add(point1); if (surfaceVertices.IndexOf(point2) < 0) { surfaceVertices.Add(point2); normals.Add(planeNormal); } originalVertices.Add(point2); } else { if (surfaceVertices.IndexOf(point2) < 0) { surfaceVertices.Add(point2); normals.Add(planeNormal); } originalVertices.Add(point2); if (surfaceVertices.IndexOf(point1) < 0) { surfaceVertices.Add(point1); normals.Add(planeNormal); } originalVertices.Add(point1); } } #endregion #region Apply Displacement if (face.dispinfo > -1) { ddispinfo_t disp = bspParser.dispInfo[face.dispinfo]; int power = Mathf.RoundToInt(Mathf.Pow(2, disp.power)); List <Vector3> dispVertices = new List <Vector3>(); Vector3 startingPosition = surfaceVertices[0]; Vector3 topCorner = surfaceVertices[1], topRightCorner = surfaceVertices[2], rightCorner = surfaceVertices[3]; #region Setting Orientation Vector3 dispStartingVertex = disp.startPosition; if (Vector3.Distance(dispStartingVertex, topCorner) < 0.01f) { Vector3 tempCorner = startingPosition; startingPosition = topCorner; topCorner = topRightCorner; topRightCorner = rightCorner; rightCorner = tempCorner; } else if (Vector3.Distance(dispStartingVertex, rightCorner) < 0.01f) { Vector3 tempCorner = startingPosition; startingPosition = rightCorner; rightCorner = topRightCorner; topRightCorner = topCorner; topCorner = tempCorner; } else if (Vector3.Distance(dispStartingVertex, topRightCorner) < 0.01f) { Vector3 tempCorner = startingPosition; startingPosition = topRightCorner; topRightCorner = tempCorner; tempCorner = rightCorner; rightCorner = topCorner; topCorner = tempCorner; } #endregion int orderNum = 0; #region Method 13 (The one and only two) Vector3 leftSide = (topCorner - startingPosition), rightSide = (topRightCorner - rightCorner); float leftSideLineSegmentationDistance = leftSide.magnitude / power, rightSideLineSegmentationDistance = rightSide.magnitude / power; for (int line = 0; line < (power + 1); line++) { for (int point = 0; point < (power + 1); point++) { Vector3 leftPoint = (leftSide.normalized * line * leftSideLineSegmentationDistance) + startingPosition; Vector3 rightPoint = (rightSide.normalized * line * rightSideLineSegmentationDistance) + rightCorner; Vector3 currentLine = rightPoint - leftPoint; Vector3 pointDirection = currentLine.normalized; float pointSideSegmentationDistance = currentLine.magnitude / power; Vector3 pointA = leftPoint + (pointDirection * pointSideSegmentationDistance * point); Vector3 dispDirectionA = bspParser.dispVerts[disp.DispVertStart + orderNum].vec; dispVertices.Add(pointA + (dispDirectionA * bspParser.dispVerts[disp.DispVertStart + orderNum].dist)); orderNum++; } } #endregion surfaceVertices = dispVertices; } #endregion #region Triangulate List <int> triangleIndices = new List <int>(); if (face.dispinfo > -1) { ddispinfo_t disp = bspParser.dispInfo[face.dispinfo]; int power = Mathf.RoundToInt(Mathf.Pow(2, disp.power)); #region Method 12 Triangulation for (int row = 0; row < power; row++) { for (int col = 0; col < power; col++) { int currentLine = row * (power + 1); int nextLineStart = (row + 1) * (power + 1); triangleIndices.Add(currentLine + col); triangleIndices.Add(currentLine + col + 1); triangleIndices.Add(nextLineStart + col); triangleIndices.Add(currentLine + col + 1); triangleIndices.Add(nextLineStart + col + 1); triangleIndices.Add(nextLineStart + col); } } #endregion } else { for (int i = 0; i < (originalVertices.Count / 2) - 0; i++) { int firstOrigIndex = i * 2, secondOrigIndex = (i * 2) + 1, thirdOrigIndex = 0; int firstIndex = surfaceVertices.IndexOf(originalVertices[firstOrigIndex]); int secondIndex = surfaceVertices.IndexOf(originalVertices[secondOrigIndex]); int thirdIndex = surfaceVertices.IndexOf(originalVertices[thirdOrigIndex]); triangleIndices.Add(thirdIndex); triangleIndices.Add(secondIndex); triangleIndices.Add(firstIndex); } } #endregion #region Map UV Points Vector3 s = Vector3.zero, t = Vector3.zero; float xOffset = 0, yOffset = 0; try { s = new Vector3(bspParser.texInfo[face.texinfo].textureVecs[0][0], bspParser.texInfo[face.texinfo].textureVecs[0][1], bspParser.texInfo[face.texinfo].textureVecs[0][2]); t = new Vector3(bspParser.texInfo[face.texinfo].textureVecs[1][0], bspParser.texInfo[face.texinfo].textureVecs[1][1], bspParser.texInfo[face.texinfo].textureVecs[1][2]); xOffset = bspParser.texInfo[face.texinfo].textureVecs[0][3]; yOffset = bspParser.texInfo[face.texinfo].textureVecs[1][3]; } catch (Exception e) { Debug.LogError(e); } Vector2[] uvPoints = new Vector2[surfaceVertices.Count]; int textureWidth = 0, textureHeight = 0; try { textureWidth = bspParser.texData[bspParser.texInfo[face.texinfo].texdata].width; textureHeight = bspParser.texData[bspParser.texInfo[face.texinfo].texdata].height; } catch (Exception e) { Debug.LogError(e); } for (int i = 0; i < uvPoints.Length; i++) { uvPoints[i] = new Vector2((Vector3.Dot(surfaceVertices[i], s) + xOffset) / textureWidth, (textureHeight - (Vector3.Dot(surfaceVertices[i], t) + yOffset)) / textureHeight); } #endregion #region Organize Mesh Data MeshHelpers.MeshData meshData = new MeshHelpers.MeshData(); meshData.vertices = surfaceVertices.ToArray(); meshData.triangles = triangleIndices.ToArray(); meshData.normals = normals.ToArray(); meshData.uv = uvPoints; #endregion #region Clear References surfaceVertices.Clear(); surfaceVertices = null; originalVertices.Clear(); originalVertices = null; normals.Clear(); normals = null; triangleIndices.Clear(); triangleIndices = null; uvPoints = null; #endregion return(meshData); }
public List <string> GetDependencies(CancellationToken cancelToken) { List <string> dependencies = new List <string>(); using (VPKParser vpkParser = new VPKParser(vpkLoc)) using (BSPParser bspParser = new BSPParser(Path.Combine(mapDir, mapName + ".bsp"))) { bool validVPK = vpkParser.IsValid(); if (!validVPK) { return(null); } bspParser.ParseData(cancelToken); if (cancelToken.IsCancellationRequested) { return(null); } //Note: If there are materials that point to textures in separate archives or there are textures used by the models whose vpk archive is not already // added by other dependencies, those archives will not be added. That would require us to read the materials and models to get what textures they use. #region Map face textures dependencies if (FaceLoadPercent > 0) { foreach (dface_t face in bspParser.faces) { if (cancelToken.IsCancellationRequested) { return(null); } texflags currentTexFlags = GetFaceTextureFlags(face, bspParser); string rawTextureLocation = GetFaceTextureLocation(face, bspParser); if (!IsUndesiredTexture(rawTextureLocation, currentTexFlags)) { string fixedLocation = VMTData.FixLocation(bspParser, vpkParser, rawTextureLocation); if (!vpkParser.FileExists(fixedLocation)) { fixedLocation = SourceTexture.FixLocation(bspParser, vpkParser, rawTextureLocation); } string dependency = vpkParser.LocateInArchive(fixedLocation); if (!string.IsNullOrEmpty(dependency) && !dependencies.Contains(dependency)) { dependencies.Add(dependency); } } } } #endregion #region Model dependencies if (ModelLoadPercent > 0) { for (int i = 0; i < bspParser.staticProps.staticPropInfo.Length; i++) { if (cancelToken.IsCancellationRequested) { return(null); } var currentPropInfo = bspParser.staticProps.staticPropInfo[i]; ushort propType = currentPropInfo.PropType; string modelFullPath = bspParser.staticProps.staticPropDict.names[propType]; modelFullPath = modelFullPath.Substring(0, modelFullPath.LastIndexOf(".")); string mdlPath = modelFullPath + ".mdl"; string vvdPath = modelFullPath + ".vvd"; string vtxPath = modelFullPath + ".vtx"; if (!vpkParser.FileExists(vtxPath)) { vtxPath = modelFullPath + ".dx90.vtx"; } string dependency = vpkParser.LocateInArchive(mdlPath); if (!string.IsNullOrEmpty(dependency) && !dependencies.Contains(dependency)) { dependencies.Add(dependency); } dependency = vpkParser.LocateInArchive(vvdPath); if (!string.IsNullOrEmpty(dependency) && !dependencies.Contains(dependency)) { dependencies.Add(dependency); } dependency = vpkParser.LocateInArchive(vtxPath); if (!string.IsNullOrEmpty(dependency) && !dependencies.Contains(dependency)) { dependencies.Add(dependency); } } } #endregion } return(dependencies); }
public VerifierResult VerifyMap(string map) { VerifierResult res = new VerifierResult(); ValveFile[] wadfiles = GetWadFiles(); var fullmap = Path.Combine(ModMapsDirectory, map); if (!File.Exists(fullmap)) { throw new Exception(string.Format("Map does not exist: {0}", fullmap)); } BSPParser bp = new BSPParser(File.OpenRead(fullmap)); if (!bp.LoadDirectoryTables()) { throw new Exception("Malformed file"); } var textureList = bp.LoadMipTexturesArray() .Where(t => t.offset1 == 0 && t.offset2 == 0 && t.offset3 == 0 && t.offset4 == 0) .Select(t => t.name.ToString()) .ToList(); string entities = bp.ReadEntities(); bp.Close(); EntityParser ep = new EntityParser(entities); var ent = ep.ReadEntities(); List <ValveFile> existingWads = new List <ValveFile>(); List <string> malformedWadFiles = new List <string>(); List <string> misnamedModDirs = new List <string>(); List <string> notExistingFiles = new List <string>(); if (ent.ContainsKey("worldspawn")) { string skyname = ent["worldspawn"][0]["skyname"]; string wadList = ent["worldspawn"][0]["wad"]; var list = Seperate(wadList); foreach (string fullReferencedWadFile in list) { string referencedRelevantWadFile = fullReferencedWadFile.GetRelevantPath(); ValveFile referencedFile = new ValveFile(referencedRelevantWadFile); ValveFile existingFile = GetWadFile(wadfiles, referencedFile); if (referencedRelevantWadFile != fullReferencedWadFile) { malformedWadFiles.Add(fullReferencedWadFile); } if (existingFile != null) { if (existingFile.Compare(referencedFile) == ValveFileDifference.EqualFile) { misnamedModDirs.Add(fullReferencedWadFile); } existingWads.Add(existingFile); } else { notExistingFiles.Add(fullReferencedWadFile); } } res.MalformedWadFiles = malformedWadFiles.ToArray(); res.MisnamedModDirs = misnamedModDirs.ToArray(); res.NotExistingFiles = notExistingFiles.ToArray(); #region Textures List <string> existingFilenames = new List <string>(); foreach (var wadFile in existingWads) { WADParser wp = new WADParser(File.OpenRead(wadFile.ToString(BaseDirectory))); existingFilenames.AddRange(wp.LoadFileArray().Select(f => f.filename.ToString().ToLower())); wp.Close(); } List <string> missingTextures = new List <string>(); foreach (var item in textureList) { if (!existingFilenames.Contains(item.ToLower())) { missingTextures.Add(item); } } res.MissingTextures = missingTextures.ToArray(); #endregion #region Sprites List <string> sprites = new List <string>(); if (ent.ContainsKey("env_sprite")) { foreach (var dict in ent["env_sprite"]) { string model = dict["model"]; if (!sprites.Contains(model)) { sprites.Add(model); } } } res.UsedSprites = sprites.ToArray(); List <string> missingSprites = new List <string>(); foreach (string sprite in sprites) { ValveFile file = GetFile(sprite); if (file == null) { missingSprites.Add(sprite); } } res.MissingSprites = missingSprites.ToArray(); #endregion #region Sounds List <string> sounds = new List <string>(); if (ent.ContainsKey("ambient_generic")) { foreach (var ambient in ent["ambient_generic"]) { if (ambient.ContainsKey("message")) { string message = Path.Combine(SoundDir, ambient["message"]); if (!sounds.Contains(message)) { sounds.Add(message); } } } } res.UsedSounds = sounds.ToArray(); List <string> missingSounds = new List <string>(); foreach (string sound in sounds) { ValveFile file = GetFile(sound); if (file == null) { missingSounds.Add(sound); } } res.MissingSounds = missingSounds.ToArray(); #endregion #region Models List <string> models = new List <string>(); foreach (var entityPair in ent) { foreach (var entity in entityPair.Value) { if (entity.ContainsKey("model")) { string model = entity["model"]; if (!model.EndsWith(".mdl")) { continue; } if (!models.Contains(model)) { models.Add(model); } } } } res.UsedModels = models.ToArray(); List <string> missingModels = new List <string>(); foreach (var model in models) { ValveFile file = GetFile(model); if (file == null) { missingModels.Add(model); } } res.MissingModels = missingModels.ToArray(); #endregion } res.UsedFileList = Sort(res.UsedSprites, res.UsedSounds, res.UsedModels); res.MissingFileList = Sort(res.MissingSprites, res.MissingSounds, res.MissingModels); return(res); }
private void Parse(BSPParser bspParser, VPKParser vpkParser) { if (vpkParser != null) { string mdlPath = modelPath + ".mdl"; string vvdPath = modelPath + ".vvd"; string vtxPath = modelPath + ".vtx"; if ((bspParser != null && bspParser.HasPakFile(mdlPath)) || (vpkParser != null && vpkParser.FileExists(mdlPath))) { if ((bspParser != null && bspParser.HasPakFile(vvdPath)) || (vpkParser != null && vpkParser.FileExists(vvdPath))) { if ((bspParser == null || !bspParser.HasPakFile(vtxPath)) && (vpkParser == null || !vpkParser.FileExists(vtxPath))) { vtxPath = modelPath + ".dx90.vtx"; } if ((bspParser != null && bspParser.HasPakFile(vtxPath)) || (vpkParser != null && vpkParser.FileExists(vtxPath))) { using (MDLParser mdl = new MDLParser()) using (VVDParser vvd = new VVDParser()) using (VTXParser vtx = new VTXParser()) { try { if (bspParser != null && bspParser.HasPakFile(mdlPath)) { bspParser.LoadPakFileAsStream(mdlPath, (stream, origOffset, byteCount) => { mdl.ParseHeader(stream, origOffset); }); } else { vpkParser.LoadFileAsStream(mdlPath, (stream, origOffset, byteCount) => { mdl.ParseHeader(stream, origOffset); }); } if (bspParser != null && bspParser.HasPakFile(vvdPath)) { bspParser.LoadPakFileAsStream(vvdPath, (stream, origOffset, byteCount) => { vvd.ParseHeader(stream, origOffset); }); } else { vpkParser.LoadFileAsStream(vvdPath, (stream, origOffset, byteCount) => { vvd.ParseHeader(stream, origOffset); }); } int mdlChecksum = mdl.header1.checkSum; int vvdChecksum = (int)vvd.header.checksum; if (mdlChecksum == vvdChecksum) { if (bspParser != null && bspParser.HasPakFile(vtxPath)) { bspParser.LoadPakFileAsStream(vtxPath, (stream, origOffset, byteCount) => { vtx.ParseHeader(stream, origOffset); }); } else { vpkParser.LoadFileAsStream(vtxPath, (stream, origOffset, byteCount) => { vtx.ParseHeader(stream, origOffset); }); } int vtxChecksum = vtx.header.checkSum; if (mdlChecksum == vtxChecksum) { if (bspParser != null && bspParser.HasPakFile(mdlPath)) { bspParser.LoadPakFileAsStream(mdlPath, (stream, origOffset, byteCount) => { mdl.Parse(stream, origOffset); }); } else { vpkParser.LoadFileAsStream(mdlPath, (stream, origOffset, byteCount) => { mdl.Parse(stream, origOffset); }); } if (bspParser != null && bspParser.HasPakFile(vvdPath)) { bspParser.LoadPakFileAsStream(vvdPath, (stream, origOffset, byteCount) => { vvd.Parse(stream, mdl.header1.rootLod, origOffset); }); } else { vpkParser.LoadFileAsStream(vvdPath, (stream, origOffset, byteCount) => { vvd.Parse(stream, mdl.header1.rootLod, origOffset); }); } if (bspParser != null && bspParser.HasPakFile(vtxPath)) { bspParser.LoadPakFileAsStream(vtxPath, (stream, origOffset, byteCount) => { vtx.Parse(stream, origOffset); }); } else { vpkParser.LoadFileAsStream(vtxPath, (stream, origOffset, byteCount) => { vtx.Parse(stream, origOffset); }); } version = mdl.header1.version; id = mdl.header1.id; if (mdl.bodyParts != null) { ReadFaceMeshes(mdl, vvd, vtx, bspParser, vpkParser); } else { Debug.LogError("SourceModel: Could not find body parts of " + modelPath); } } else { Debug.LogError("SourceModel: MDL and VTX checksums don't match (" + mdlChecksum + " != " + vtxChecksum + ") vtxver(" + vtx.header.version + ") for " + modelPath); } } else { Debug.LogError("SourceModel: MDL and VVD checksums don't match (" + mdlChecksum + " != " + vvdChecksum + ") for " + modelPath); } } catch (System.Exception e) { Debug.LogError("SourceModel: " + e.ToString()); } } } else { Debug.LogError("SourceModel: Could not find vtx file (" + vtxPath + ")"); } } else { Debug.LogError("SourceModel: Could not find vvd file (" + vvdPath + ")"); } } else { Debug.LogError("SourceModel: Could not find mdl file (" + mdlPath + ")"); } } else { Debug.LogError("SourceModel: VPK parser is null"); } }
void Awake() { parser = new BSPParser(RESOURCESPATH + FILENAME); _textures = parser.Textures; _vertexes = parser.Vertexes; _planes = parser.Planes; _faces = parser.Faces; _models = parser.Models; _meshverts = parser.Meshverts; _nodes = parser.Nodes; _leafs = parser.Leafs; _leaffaces = parser.Leaffaces; _leafbrushes = parser.Leafbrushes; _brushes = parser.Brushes; _brushsides = parser.Brushsides; _visdata = parser.Visdata; _playerstart = parser.GetPlayerStartPosition(); }