private void Start()
 {
     model = LoadModel(vpkPath, modelPath, flatTextures, maxTextureSize);
     if (model != null)
     {
         model.InstantiateGameObject().transform.SetParent(transform, false);
     }
 }
Esempio n. 2
0
    //public void BuildMap()
    //{
    //    StartCoroutine("StartBuilding");
    //}

    public void BuildMap()
    {
        //mapTextures = new List<Texture2D>();
        //textureLocations = new List<string>();
        bool usingPlainTextures = false;

        try
        {
            Debug.Log(mapLocation + mapName + ".bsp");
            if (mapLocation.Length > 0 && File.Exists(mapLocation + mapName + ".bsp"))
            {
                mapFile = new FileStream(mapLocation + mapName + ".bsp", FileMode.Open);
            }
            else if (File.Exists("Assets\\Resources\\Maps\\" + mapName + ".bsp"))
            {
                mapFile = new FileStream("Assets\\Resources\\Maps\\" + mapName + ".bsp", FileMode.Open);
            }
        }
        catch (System.Exception e) { Debug.Log(e.Message); }

        if (mapFile != null)
        {
            ReadFile();

            #region Load Static Props
            for (int i = 0; i < staticProps.staticPropDict.names.Length; i++)
            {
                string modelName = staticProps.staticPropDict.names[i], modelLocation = staticProps.staticPropDict.names[i];
                modelName     = modelName.Substring(modelName.LastIndexOf("/") + 1);
                modelName     = modelName.Substring(0, modelName.LastIndexOf("."));
                modelLocation = modelLocation.Substring(0, modelLocation.LastIndexOf("/"));

                SourceModel.GrabModel(modelName, ApplicationPreferences.modelsDir + modelLocation);
            }
            #endregion

            mainSurfaceMaterial = Resources.Load <Material>("Materials/MapMaterial");
            mapGameObject       = new GameObject(mapName);

            List <FaceMesh> allFaces = new List <FaceMesh>();
            #region Parse Faces
            foreach (dface_t face in faces)
            {
                FaceMesh currentFace = new FaceMesh();
                currentFace.face = face;

                #region Get Texture Info
                //texflags textureFlag = texflags.SURF_NODRAW;
                try { currentFace.textureFlag = ((texflags)texInfo[face.texinfo].flags); }
                catch (System.Exception) { }

                currentFace.rawTexture = textureStringData.Substring(Mathf.Abs(texStringTable[Mathf.Abs(texData[Mathf.Abs(texInfo[Mathf.Abs(face.texinfo)].texdata)].nameStringTableID)]));
                currentFace.rawTexture = currentFace.rawTexture.Substring(0, currentFace.rawTexture.IndexOf(BSPParser.TEXTURE_STRING_DATA_SPLITTER));
                SourceTexture srcTexture = SourceTexture.GrabTexture(currentFace.rawTexture);
                currentFace.textureLocation = srcTexture.location;

                currentFace.s       = new Vector3(texInfo[face.texinfo].textureVecs[0][0], texInfo[face.texinfo].textureVecs[0][2], texInfo[face.texinfo].textureVecs[0][1]);
                currentFace.t       = new Vector3(texInfo[face.texinfo].textureVecs[1][0], texInfo[face.texinfo].textureVecs[1][2], texInfo[face.texinfo].textureVecs[1][1]);
                currentFace.xOffset = texInfo[face.texinfo].textureVecs[0][3];
                currentFace.yOffset = texInfo[face.texinfo].textureVecs[1][3];

                bool undesired = false;
                foreach (string undesiredTexture in undesiredTextures)
                {
                    if (currentFace.rawTexture.Equals(undesiredTexture))
                    {
                        undesired = true; break;
                    }
                }
                #endregion

                if (!undesired && (currentFace.textureFlag & texflags.SURF_SKY2D) != texflags.SURF_SKY2D && (currentFace.textureFlag & texflags.SURF_SKY) != texflags.SURF_SKY && (currentFace.textureFlag & texflags.SURF_NODRAW) != texflags.SURF_NODRAW && (currentFace.textureFlag & texflags.SURF_SKIP) != texflags.SURF_SKIP)
                {
                    //if(!mapTextures.ContainsKey(srcTexture.location)) mapTextures.Add(srcTexture.location, srcTexture);
                    if (textureLocations.IndexOf(srcTexture.location) < 0)
                    {
                        mapTextures.Add(srcTexture);
                        textureLocations.Add(srcTexture.location);
                    }

                    currentFace.mesh = MakeFace(face);
                    currentFace.localToWorldMatrix = mapGameObject.transform.localToWorldMatrix;
                    allFaces.Add(currentFace);
                }
            }
            #endregion

            //Debug.Log("Parsed " + allFaces.Count + " Faces");

            if (!ApplicationPreferences.combineMeshes)
            {
                foreach (FaceMesh faceMesh in allFaces)
                {
                    //GameObject faceGO = new GameObject(faceMesh.textureLocation);
                    GameObject faceGO = new GameObject(faceMesh.rawTexture);
                    faceGO.transform.parent = mapGameObject.transform;
                    MeshFilter theFilter = faceGO.AddComponent <MeshFilter>();
                    theFilter.mesh = faceMesh.mesh;

                    #region Add Vertices as Children

                    /*foreach (Vector3 vertex in theFilter.mesh.vertices)
                     * {
                     *  GameObject sphereVertex = new GameObject();
                     *  sphereVertex.name = vertex.ToString();
                     *  sphereVertex.transform.position = vertex;
                     *  sphereVertex.transform.localScale = new Vector3(10f, 10f, 10f);
                     *  sphereVertex.transform.parent = faceGO.transform;
                     * }*/
                    #endregion

                    #region Set Material of GameObject
                    Material faceMaterial = mainSurfaceMaterial;

                    //int textureIndex = textureLocations.IndexOf(faceMesh.textureLocation);
                    //int textureIndex = textureLocations.IndexOf(faceMesh.rawTexture);
                    Texture2D faceTexture = null;
                    if (textureLocations.IndexOf(faceMesh.textureLocation) > -1)
                    {
                        faceTexture = mapTextures[textureLocations.IndexOf(faceMesh.textureLocation)].texture;
                    }
                    if (faceTexture != null)
                    {
                        faceMaterial = new Material(ApplicationPreferences.mapMaterial);
                        faceMaterial.mainTextureScale  = new Vector2(1, 1);
                        faceMaterial.mainTextureOffset = new Vector2(0, 0);
                        faceMaterial.mainTexture       = faceTexture;
                        faceTexture = null;
                    }
                    faceGO.AddComponent <MeshRenderer>().material = faceMaterial;
                    #endregion
                }

                #region Static Props
                GameObject staticPropsObject = new GameObject("StaticProps");
                staticPropsObject.transform.parent = mapGameObject.transform;
                for (int i = 0; i < staticProps.staticPropInfo.Length; i++)
                {
                    string modelName = staticProps.staticPropDict.names[staticProps.staticPropInfo[i].PropType], modelLocation = staticProps.staticPropDict.names[staticProps.staticPropInfo[i].PropType];
                    modelName     = modelName.Substring(modelName.LastIndexOf("/") + 1);
                    modelName     = modelName.Substring(0, modelName.LastIndexOf("."));
                    modelLocation = modelLocation.Substring(0, modelLocation.LastIndexOf("/"));

                    SourceModel propModel   = SourceModel.GrabModel(modelName, ApplicationPreferences.modelsDir + modelLocation);
                    GameObject  propModelGO = propModel.InstantiateGameObject();
                    propModelGO.transform.position      = staticProps.staticPropInfo[i].Origin;
                    propModelGO.transform.localRotation = Quaternion.Euler(staticProps.staticPropInfo[i].Angles.x, staticProps.staticPropInfo[i].Angles.y + 0, staticProps.staticPropInfo[i].Angles.z);
                    propModelGO.transform.parent        = staticPropsObject.transform;
                }
                #endregion

                //Debug.Log("Made Seperate Meshes");
            }
            else
            {
                #region Add Static Prop Meshes to allFaces and mapTextures
                for (int i = 0; i < staticProps.staticPropInfo.Length; i++)
                {
                    string modelName = staticProps.staticPropDict.names[staticProps.staticPropInfo[i].PropType], modelLocation = staticProps.staticPropDict.names[staticProps.staticPropInfo[i].PropType];
                    modelName     = modelName.Substring(modelName.LastIndexOf("/") + 1);
                    modelName     = modelName.Substring(0, modelName.LastIndexOf("."));
                    modelLocation = modelLocation.Substring(0, modelLocation.LastIndexOf("/"));

                    SourceModel propModel = SourceModel.GrabModel(modelName, ApplicationPreferences.modelsDir + modelLocation);
                    for (int j = 0; j < propModel.modelMeshes.Length; j++)
                    {
                        FaceMesh propMesh = new FaceMesh();
                        propMesh.mesh = propModel.modelMeshes[j];
                        if (j < propModel.modelTextures.Length)
                        {
                            if (textureLocations.IndexOf(propModel.modelTextures[j].location) < 0)
                            {
                                mapTextures.Insert(0, propModel.modelTextures[j]);
                                textureLocations.Insert(0, propModel.modelTextures[j].location);
                            }
                            propMesh.textureLocation = propModel.modelTextures[j].location;

                            #region GameObject for Position and Rotation
                            GameObject propModelGO = new GameObject("Empty");
                            propModelGO.transform.position      = staticProps.staticPropInfo[i].Origin;
                            propModelGO.transform.localRotation = Quaternion.Euler(staticProps.staticPropInfo[i].Angles.x, staticProps.staticPropInfo[i].Angles.y + 0, staticProps.staticPropInfo[i].Angles.z);
                            propMesh.localToWorldMatrix         = propModelGO.transform.localToWorldMatrix;
                            Object.DestroyImmediate(propModelGO);
                            #endregion
                        }
                        allFaces.Add(propMesh);
                    }
                }
                #endregion
                #region Create Atlas & Remap UVs
                AtlasMapper customAtlas = new AtlasMapper();
                if (usingPlainTextures)
                {
                    customAtlas.cushion = 0;
                }
                customAtlas.AddTextures(GetTexturesAsArray());
                Texture2D packedMapTextures = customAtlas.atlas;
                Rect[]    uvReMappers       = customAtlas.mappedUVs;
                Material  mapAtlas          = new Material(ApplicationPreferences.mapAtlasMaterial);
                if (usingPlainTextures)
                {
                    mapAtlas.SetFloat("_uv1FracOffset", 0.07f);
                }
                mapAtlas.mainTextureScale = new Vector2(1f, 1f);
                mapAtlas.mainTexture      = packedMapTextures;
                //mapAtlas.mainTexture.wrapMode = TextureWrapMode.Clamp;
                //List<string> textureKeys = mapTextures.Keys.ToList();
                for (int i = 0; i < allFaces.Count; i++)
                {
                    //if (i < 10) { Debug.Log(i + " Triangles: " + allFaces[i].mesh.triangles.Length); }
                    int textureIndex = textureLocations.IndexOf(allFaces[i].textureLocation);
                    //int textureIndex = textureKeys.IndexOf(allFaces[i].textureLocation);
                    //Texture2D faceTexture = null;
                    if (textureIndex > -1 && textureIndex < uvReMappers.Length)
                    {
                        //faceTexture = mapTextures[textureIndex];
                        Rect      surfaceTextureRect   = uvReMappers[textureIndex];
                        Mesh      surfaceMesh          = allFaces[i].mesh;
                        Vector2[] atlasTexturePosition = new Vector2[surfaceMesh.uv.Length];
                        Vector2[] atlasTextureSize     = new Vector2[surfaceMesh.uv.Length];
                        for (int j = 0; j < atlasTexturePosition.Length; j++)
                        {
                            atlasTexturePosition[j] = new Vector2(surfaceTextureRect.x + 0.0f, surfaceTextureRect.y + 0.0f);
                            atlasTextureSize[j]     = new Vector2(surfaceTextureRect.width - 0.0f, surfaceTextureRect.height - 0.0f);
                        }
                        surfaceMesh.uv2 = atlasTexturePosition;
                        surfaceMesh.uv3 = atlasTextureSize;
                    }
                }
                #endregion
                Debug.Log("Created Atlas and Remapped UVs");
                #region Calculate Minimum Submeshes Needed
                List <List <int> > combinesIndices = new List <List <int> >();
                combinesIndices.Add(new List <int>());
                int vertexCount = 0;
                for (int i = 0; i < allFaces.Count; i++)
                {
                    if (vertexCount + allFaces[i].mesh.vertices.Length >= ushort.MaxValue)
                    {
                        combinesIndices.Add(new List <int>());
                        vertexCount = 0;
                    }

                    combinesIndices[combinesIndices.Count - 1].Add(i);
                    vertexCount += allFaces[i].mesh.vertices.Length;
                }
                #endregion
                Debug.Log("Calculated Submeshes needed");
                #region Combine Meshes to Submeshes
                if (combinesIndices.Count == 1)
                {
                    CombineInstance[] currentCombine = new CombineInstance[combinesIndices[0].Count];
                    for (int i = 0; i < currentCombine.Length; i++)
                    {
                        currentCombine[i].mesh      = allFaces[combinesIndices[0][i]].mesh;
                        currentCombine[i].transform = allFaces[combinesIndices[0][i]].localToWorldMatrix;
                    }

                    Mesh combinedMesh = new Mesh();
                    combinedMesh.name = "Custom Combined Mesh";
                    combinedMesh.CombineMeshes(currentCombine);
                    mapGameObject.AddComponent <MeshFilter>().mesh       = combinedMesh;
                    mapGameObject.AddComponent <MeshRenderer>().material = mapAtlas;
                }
                else
                {
                    GameObject[] partialMeshes = new GameObject[combinesIndices.Count];
                    for (int i = 0; i < combinesIndices.Count; i++)
                    {
                        CombineInstance[] currentCombine = new CombineInstance[combinesIndices[i].Count];
                        for (int j = 0; j < currentCombine.Length; j++)
                        {
                            currentCombine[j].mesh      = allFaces[combinesIndices[i][j]].mesh;
                            currentCombine[j].transform = allFaces[combinesIndices[i][j]].localToWorldMatrix;
                        }

                        partialMeshes[i] = new GameObject(mapName + " Part " + (i + 1));
                        Mesh combinedMesh = new Mesh();
                        combinedMesh.name = "Custom Combined Mesh " + (i + 1);
                        combinedMesh.CombineMeshes(currentCombine);
                        partialMeshes[i].AddComponent <MeshFilter>().mesh       = combinedMesh;
                        partialMeshes[i].AddComponent <MeshRenderer>().material = mapAtlas;
                        partialMeshes[i].AddComponent <MeshCollider>();
                        partialMeshes[i].transform.parent = mapGameObject.transform;
                    }
                }
                #endregion
                //Debug.Log("Combined Meshes into Submeshes");
            }
        }
        else
        {
            mapGameObject = Object.Instantiate(Resources.Load("Models/CSGOMaps/" + mapName)) as GameObject;
        }

        //SaveUVValues("C:\\Users\\oxter\\Documents\\" + mapName + "_UV.txt");
    }