//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"); }
public static SourceModel GrabModel(string name, string location) { SourceModel model = null; if (loadedModels.ContainsKey(location + name)) { model = loadedModels[location + name]; } else { model = new SourceModel(name, location); model.modelPrefab = new GameObject(model.modelName); model.modelPrefab.transform.parent = staticPropLibrary.transform; model.modelPrefab.SetActive(false); model.ReadFiles(); if (model.mdl == null) { Debug.Log("MDL missing"); return(null); } if (model.mdl.bodyParts == null) { Debug.Log("Body Parts missing"); return(null); } #region Grabbing Textures //if(model.mdl.texturePaths.Length == model.mdl.textures.Length) //{ model.modelTextures = new SourceTexture[model.mdl.textures.Length]; for (int i = 0; i < model.modelTextures.Length; i++) { string texturePath = "", textureName = ""; if (model.mdl.texturePaths != null && model.mdl.texturePaths.Length > 0 && model.mdl.texturePaths[0] != null) { texturePath = model.mdl.texturePaths[0]; } if (model.mdl.textures[i] != null) { textureName = model.mdl.textures[i].name; } model.modelTextures[i] = SourceTexture.GrabTexture(texturePath + textureName); //Debug.Log("Attempted to grab texture: " + model.modelTextures[i].location); } //} /*for (int i = 0; i < model.mdl.texturePaths.Length; i++) * { * Debug.Log(model.mdl.texturePaths[i]); * } * for (int i = 0; i < model.mdl.textures.Length; i++) * { * Debug.Log(model.mdl.textures[i].name); * }*/ #endregion #region Building int textureIndex = 0; List <Mesh> meshes = new List <Mesh>(); for (int i = 0; i < model.mdl.bodyParts.Length; i++) { GameObject bodyPartRepresentation = new GameObject(model.mdl.bodyParts[i].name); bodyPartRepresentation.transform.parent = model.modelPrefab.transform; for (int j = 0; j < model.mdl.bodyParts[i].models.Length; j++) { GameObject modelRepresentation = new GameObject(new string(model.mdl.bodyParts[i].models[j].name)); modelRepresentation.transform.parent = bodyPartRepresentation.transform; int currentPosition = 0; for (int k = 0; k < model.mdl.bodyParts[i].models[j].theMeshes.Length; k++) { GameObject meshRepresentation = new GameObject(model.mdl.bodyParts[i].models[j].theMeshes[k].id.ToString()); meshRepresentation.transform.parent = modelRepresentation.transform; Vector3[] vertices = new Vector3[model.mdl.bodyParts[i].models[j].theMeshes[k].vertexData.lodVertexCount[0]]; Vector3[] normals = new Vector3[model.mdl.bodyParts[i].models[j].theMeshes[k].vertexData.lodVertexCount[0]]; Vector2[] uv = new Vector2[model.mdl.bodyParts[i].models[j].theMeshes[k].vertexData.lodVertexCount[0]]; for (int l = 0; l < vertices.Length; l++) { if (currentPosition < model.vvd.vertices[0].Length) { vertices[l] = model.vvd.vertices[0][currentPosition].m_vecPosition; } if (currentPosition < model.vvd.vertices[0].Length) { normals[l] = model.vvd.vertices[0][currentPosition].m_vecNormal; } if (currentPosition < model.vvd.vertices[0].Length) { uv[l] = model.vvd.vertices[0][currentPosition].m_vecTexCoord; } currentPosition++; } int[] triangles = new int[model.vtx.bodyParts[i].theVtxModels[j].theVtxModelLods[0].theVtxMeshes[k].theVtxStripGroups[0].theVtxIndices.Length]; for (int l = 0; l < model.vtx.bodyParts[i].theVtxModels[j].theVtxModelLods[0].theVtxMeshes[k].theVtxStripGroups[0].theVtxIndices.Length; l++) { triangles[l + 0] = model.vtx.bodyParts[i].theVtxModels[j].theVtxModelLods[0].theVtxMeshes[k].theVtxStripGroups[0].theVtxVertices[model.vtx.bodyParts[i].theVtxModels[j].theVtxModelLods[0].theVtxMeshes[k].theVtxStripGroups[0].theVtxIndices[l + 0]].originalMeshVertexIndex; } Mesh mesh = new Mesh(); mesh.name = "Custom Mesh"; mesh.vertices = vertices; mesh.triangles = triangles; mesh.normals = normals; mesh.uv = uv; meshes.Add(mesh); MeshFilter mesher = meshRepresentation.AddComponent <MeshFilter>(); mesher.sharedMesh = mesh; Material meshMaterial = new Material(ApplicationPreferences.playerMaterial); if (model.modelTextures != null && textureIndex < model.modelTextures.Length) { meshMaterial.mainTexture = model.modelTextures[textureIndex].texture; textureIndex++; } meshRepresentation.AddComponent <MeshRenderer>().material = meshMaterial; meshRepresentation.AddComponent <MeshCollider>(); } } } model.modelMeshes = meshes.ToArray(); #endregion } return(model); }