Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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 + ")");
            }
        }
Esempio n. 4
0
        /*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);
        }
Esempio n. 5
0
        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);
        }