public SourceModel LoadModel(string vpkLoc, string modelLoc, bool flatTextures = false, int maxTextureSize = 2048) { SourceTexture.averageTextures = flatTextures; SourceTexture.maxTextureSize = maxTextureSize; SourceModel model = null; using (VPKParser vpk = new VPKParser(vpkPath)) model = SourceModel.GrabModel(null, vpk, modelPath); return(model); }
private void ParseModel(string name, string location) { SourceModel model = SourceModel.GrabModel(name, location); }
//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"); }