public static Mesh[] ConvertToMeshes(UMeshData lMeshData) { Vector3[] lPosVerts = lMeshData.PosVertices; Vector3[] lUVVerts = lMeshData.UVVertices; int lMeshCount = lMeshData.MeshFaceInfos.Length; Mesh[] lMeshes = new Mesh[lMeshCount]; for (int m = 0; m < lMeshCount; m++) { Mesh lMesh = new Mesh(); FaceInfo[] lFaceInfos = lMeshData.MeshFaceInfos[m]; int lVertCount = 0; int lTriCount = 0; for (int f = 0; f < lFaceInfos.Length; f++) { lVertCount += lFaceInfos[f].Indices.Length; if (lFaceInfos[f].Indices.Length > 2) { lTriCount += lFaceInfos[f].Indices.Length - 2; } } int[] lTriangles = new int[lTriCount * 3]; int lTriIndex = 0; if (m == 0) { for (int i = 0; i < lFaceInfos.Length; i++) { for (int j = 0; j < lFaceInfos[i].Indices.Length - 2; j++) { lTriangles[lTriIndex++] = lFaceInfos[i].Indices[0]; lTriangles[lTriIndex++] = lFaceInfos[i].Indices[j + 1]; lTriangles[lTriIndex++] = lFaceInfos[i].Indices[j + 2]; } } lMesh.vertices = lMeshData.PosVertices; lMesh.triangles = lTriangles; lMesh.RecalculateNormals(); lMesh.RecalculateTangents(); lMesh.RecalculateBounds(); lMesh.name = "Collider Mesh"; lMeshes[0] = lMesh; } else { Vector3[] lNewVerts = new Vector3[lVertCount]; Vector3[] lNormals = new Vector3[lVertCount]; Vector2[] lUVs = new Vector2[lVertCount]; int lVertIndex = 0; int[][] lNewIndices = new int[lFaceInfos.Length][]; for (int f = 0; f < lFaceInfos.Length; f++) { FaceInfo lFaceInfo = lFaceInfos[f]; Plane lPlane = lFaceInfo.Plane; TextureData lTexData = lPlane.TextureData; int[] lIndices = lFaceInfo.Indices; float lMinAngle = 360f; AutoUVDirection lDir = AutoUVDirection.XPos; for (int j = 0; j < s_Directions.Length; j++) { float lAngle = Vector3.Angle(-lPlane.Normal, s_Directions[j]) - s_DirectionTolerance[j]; if (lMinAngle > lAngle) { lMinAngle = lAngle; lDir = (AutoUVDirection)j; } } lNewIndices[f] = new int[lIndices.Length]; for (int j = 0; j < lIndices.Length; j++) { Vector3 lVertPos = lPosVerts[lIndices[j]]; Vector3 lVertUV = lUVVerts[lIndices[j]]; //lVertPos.x = (int)((lVertPos.x + 0.5f) * 64f + 0f) / 64f; //lVertPos.y = (int)((lVertPos.y + 0.5f) * 64f + 0f) / 64f; //lVertPos.z = (int)((lVertPos.z + 0.5f) * 64f + 0f) / 64f; lNewVerts[lVertIndex] = lVertPos; lNormals[lVertIndex] = -lPlane.Normal; lUVs[lVertIndex] = GetProjectionCoord(lDir, lVertUV); lUVs[lVertIndex] = Quaternion.Euler(0f, 0f, -lTexData.Angle) * lUVs[lVertIndex]; lUVs[lVertIndex] *= lTexData.Scale; lUVs[lVertIndex] += lTexData.Offset; lNewIndices[f][j] = lVertIndex; lVertIndex++; } for (int j = 0; j < lNewIndices[f].Length - 2; j++) { lTriangles[lTriIndex++] = lNewIndices[f][0]; lTriangles[lTriIndex++] = lNewIndices[f][j + 1]; lTriangles[lTriIndex++] = lNewIndices[f][j + 2]; } } if (lVertIndex >= 3) { lMesh.vertices = lNewVerts; lMesh.triangles = lTriangles; lMesh.normals = lNormals; lMesh.uv = lUVs; lMesh.RecalculateTangents(); lMesh.RecalculateBounds(); lMesh.name = "Visible Mesh"; lMeshes[m] = lMesh; } else { lMeshes[m] = null; } } } return(lMeshes); }
public static void ConvertMapToUnityObjects(ConvertMapSettings lSettings) { s_Settings = lSettings; //EditorGUI.BeginChangeCheck(); if (s_Settings.UsingHDRPMaterials) { s_BaseColourMapID = Shader.PropertyToID("_BaseColorMap"); s_EmissionMapID = Shader.PropertyToID("_EmissiveColorMap"); s_EmissionColorID = Shader.PropertyToID("_EmissiveColor"); s_EmissionColorLDRID = Shader.PropertyToID("_EmissiveColor"); s_CutoffEnabledID = Shader.PropertyToID("_EmissiveColor"); s_CutoffAlphaID = Shader.PropertyToID("_AlphaCutoff"); } else { s_BaseColourMapID = Shader.PropertyToID("_MainTex"); s_EmissionMapID = Shader.PropertyToID("_EmissionMap"); s_EmissionColorID = Shader.PropertyToID("_EmissionColor"); s_CutoffEnabledID = Shader.PropertyToID("_EmissiveColor"); s_CutoffAlphaID = Shader.PropertyToID("_Cutoff"); } s_MaterialDic = new Dictionary <string, Material>(s_Settings.TexDefs.Textures.Length); s_MaterialList = new List <Material>(s_Settings.TexDefs.Textures.Length); QMapLevel[] lCurrentLevels = GameObject.FindObjectsOfType <QMapLevel>(); for (int i = 0; i < lCurrentLevels.Length; i++) { GameObject.DestroyImmediate(lCurrentLevels[i].gameObject); } GameObject lLevelObject = new GameObject(s_Settings.MapFile.name); QMapLevel lQMap = lLevelObject.AddComponent <QMapLevel>(); lQMap.EntDefs = s_Settings.EntDefs; lLevelObject.isStatic = true; LevelData lLevelData = MapParser.ParseMapToLevelData(s_Settings.MapFile); int lBrushCount = 0; int lTotalBrushes = 0; for (int i = 0; i < lLevelData.Entities.Length; i++) { lTotalBrushes += lLevelData.Entities[i].Brushes.Length; } List <UEntity> lUEnts = new List <UEntity>(lLevelData.Entities.Length); List <Vector3> lAllVerts = new List <Vector3>(10000); for (int i = 0; i < lLevelData.Entities.Length; i++) { List <Vector3> lEntityVerts = new List <Vector3>(1000); QEntity lQEnt = lLevelData.Entities[i]; EntDef lEntDef = s_Settings.EntDefs.GetDefinition(lQEnt.Classname); GameObject lEntGO = null; UEntity lUEnt = null; if (lEntDef.Classname == null) { lEntGO = new GameObject(i + " NULL Classname"); lUEnt = lEntGO.AddComponent <UEmptyEntity>(); } else if (lEntDef.ConvertedPrefab != null) { lEntGO = GameObject.Instantiate(lEntDef.ConvertedPrefab).gameObject; lEntGO.name = i + " " + lQEnt.Classname; lUEnt = lEntGO.GetComponent <UEntity>(); } else if (lEntDef.RuntimePrefab != null) { lEntGO = new GameObject(i + " " + lQEnt.Classname); lUEnt = lEntGO.AddComponent <UEntity>(); } else { lEntGO = new GameObject(i + " " + lQEnt.Classname); lUEnt = lEntGO.AddComponent <UEmptyEntity>(); } lUEnts.Add(lUEnt); lEntGO.isStatic = lEntDef.IsStatic; lEntGO.layer = lEntDef.EntLayer.LayerIndex; lEntGO.transform.parent = lLevelObject.transform; List <GameObject> lBrushes = new List <GameObject>(); List <ConvexMeshData> lConvexMeshDatas = new List <ConvexMeshData>(); for (int j = 0; j < lQEnt.Brushes.Length; j++) { QBrush lBrush = lQEnt.Brushes[j]; lBrushCount++; CMesh lCMesh = ClipMesh.CreateConvexPolyhedron(lBrush.Planes); List <Vector3> lBrushVertList = new List <Vector3>(); for (int v = 0; v < lCMesh.V.Length; v++) { if (lCMesh.V[v].Visible) { lBrushVertList.Add(lCMesh.V[v].Position); } } Vector3 lMin; Vector3 lMax; GetMinMax(lBrushVertList.ToArray(), out lMin, out lMax); Vector3 lSize = lMax - lMin; Vector3 lMidPointDelta = lMin + lSize * 0.5f; lCMesh = ClipMesh.CreateConvexPolyhedron(lBrush.Planes, lMidPointDelta, lSize + Vector3.one * 0.2f); lBrushVertList.Clear(); for (int v = 0; v < lCMesh.V.Length; v++) { if (lCMesh.V[v].Visible) { lBrushVertList.Add(lCMesh.V[v].Position); } } GetMinMax(lBrushVertList.ToArray(), out lMin, out lMax); lAllVerts.AddRange(lBrushVertList); lEntityVerts.AddRange(lBrushVertList); lSize = lMax - lMin; lMidPointDelta = lMin + lSize * 0.5f; UMeshData lMeshData = lCMesh.GetMeshInformation(lMidPointDelta); Texture[] lTextures = FetchTextures(lMeshData); UpdateMaterials(lTextures); UpdateMeshData(ref lMeshData, lTextures); lConvexMeshDatas.Add(new ConvexMeshData(lMeshData, lMidPointDelta)); Mesh[] lNewMeshes = UMeshCreator.ConvertToMeshes(lMeshData); #if UNITY_EDITOR if (s_Settings.AutoGenerateUV2s) { for (int m = 1; m < lNewMeshes.Length; m++) { UnwrapParam lParam = new UnwrapParam(); lParam.angleError = 0.05f; lParam.areaError = 0.05f; lParam.hardAngle = 85f; lParam.packMargin = 2f; Unwrapping.GenerateSecondaryUVSet(lNewMeshes[m], lParam); } } #endif if (lEntDef.HasCollider || lEntDef.HasMesh) { GameObject lColliderGO = new GameObject("Brush " + j); lBrushes.Add(lColliderGO); if (lEntDef.HasCollider) { lColliderGO.transform.position = lMidPointDelta; lColliderGO.transform.parent = lEntGO.transform; lColliderGO.isStatic = lEntDef.IsStatic; lColliderGO.layer = lEntDef.ColLayer.LayerIndex; MeshCollider lMCollider = lColliderGO.AddComponent <MeshCollider>(); lMCollider.sharedMesh = lNewMeshes[0]; lMCollider.convex = true; lMCollider.isTrigger = lEntDef.IsTrigger; //if (s_Settings.SaveLevelAsAsset) //AssetDatabase.CreateAsset(lNewMeshes[0], GetAssetPath(lEntGO.name, lColliderGO.name, lNewMeshes[0].name)); } if (lEntDef.HasMesh) { for (int m = 1; m < lNewMeshes.Length; m++) { GameObject lMeshGO = new GameObject("Mesh " + (m - 1)); lMeshGO.transform.position = lMidPointDelta; lMeshGO.transform.parent = lColliderGO.transform; lMeshGO.isStatic = lEntDef.IsStatic; lMeshGO.layer = lEntDef.MeshLayer.LayerIndex; MeshFilter lMFilter = lMeshGO.AddComponent <MeshFilter>(); MeshRenderer lMRender = lMeshGO.AddComponent <MeshRenderer>(); lMRender.sharedMaterial = s_MaterialDic[lTextures[m - 1].name]; lMRender.receiveShadows = true; lMRender.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; lMRender.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion; lMFilter.mesh = lNewMeshes[m]; //if (s_Settings.SaveLevelAsAsset) //AssetDatabase.CreateAsset(lNewMeshes[m], GetAssetPath(lEntGO.name, lColliderGO.name, lMeshGO.name, lNewMeshes[m].name)); /** * * Add Area Lights * **/ TexDef lTexDef; if (s_Settings.TexDefs.HasDefinition(lTextures[m - 1].name, out lTexDef) && lTexDef.HasAreaLight) { GameObject lAreaLightGO = new GameObject("AreaLight " + (m - 1)); lAreaLightGO.transform.position = lMidPointDelta; lAreaLightGO.transform.parent = lMeshGO.transform; lAreaLightGO.isStatic = lEntDef.IsStatic; //lAreaLightGO.layer = LayerMask.NameToLayer("AreaLight"); lAreaLightGO.AddComponent <DestroyObjectOnSpawn>(); MeshFilter lALMFilter = lAreaLightGO.AddComponent <MeshFilter>(); MeshRenderer lALMRender = lAreaLightGO.AddComponent <MeshRenderer>(); lALMRender.sharedMaterial = s_MaterialDic[lTextures[m - 1].name + "_AreaLightMAT"]; lALMRender.receiveShadows = false; lALMRender.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; lALMRender.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion; Mesh lAreaLightMesh = new Mesh(); FaceInfo[] lFaceInfos = lMeshData.MeshFaceInfos[m]; int lVertCount = 0; int lTriCount = 0; for (int f = 0; f < lFaceInfos.Length; f++) { lVertCount += lFaceInfos[f].Indices.Length; if (lFaceInfos[f].Indices.Length > 2) { lTriCount += lFaceInfos[f].Indices.Length - 2; } } int lTriIndex = 0; Vector3[] lNewVerts = new Vector3[lVertCount]; Vector3[] lNormals = new Vector3[lVertCount]; int[] lTriangles = new int[lTriCount * 3]; int[][] lNewIndices = new int[lFaceInfos.Length][]; int lVertIndex = 0; Vector3[] lPosVerts = lMeshData.PosVertices; Vector3[] lUVVerts = lMeshData.UVVertices; for (int f = 0; f < lFaceInfos.Length; f++) { FaceInfo lFaceInfo = lFaceInfos[f]; Plane lPlane = lFaceInfo.Plane; int[] lIndices = lFaceInfo.Indices; lNewIndices[f] = new int[lIndices.Length]; for (int v = 0; v < lIndices.Length; v++) { Vector3 lVertPos = lPosVerts[lIndices[v]]; Vector3 lVertUV = lUVVerts[lIndices[v]]; lNewVerts[lVertIndex] = (lVertPos * lTexDef.AreaSizeScale) - lPlane.Normal * lTexDef.AreaDisplacement; lNormals[lVertIndex] = -lPlane.Normal; lNewIndices[f][v] = lVertIndex; lVertIndex++; } for (int v = 0; v < lNewIndices[f].Length - 2; v++) { lTriangles[lTriIndex++] = lNewIndices[f][0]; lTriangles[lTriIndex++] = lNewIndices[f][v + 1]; lTriangles[lTriIndex++] = lNewIndices[f][v + 2]; } } lAreaLightMesh.vertices = lNewVerts; lAreaLightMesh.triangles = lTriangles; lAreaLightMesh.normals = lNormals; lAreaLightMesh.RecalculateTangents(); lAreaLightMesh.RecalculateBounds(); lAreaLightMesh.name = "Area Light Mesh"; #if UNITY_EDITOR Unwrapping.GenerateSecondaryUVSet(lAreaLightMesh); // TODO May be always needed #endif lALMFilter.mesh = lAreaLightMesh; //if (s_Settings.SaveLevelAsAsset) //AssetDatabase.CreateAsset(lAreaLightMesh, GetAssetPath(lEntGO.name, lColliderGO.name, lMeshGO.name, lAreaLightMesh.name)); } } } } } { List <Vector3> lConvexVertList = new List <Vector3>(); List <FaceInfo> lFaceList = new List <FaceInfo>(); int lIndexShift = 0; for (int c = 0; c < lConvexMeshDatas.Count; c++) { int lVertCount = lConvexMeshDatas[c].MeshData.PosVertices.Length; Vector3 lDeltaPos = lConvexMeshDatas[c].DeltaPos; for (int v = 0; v < lVertCount; v++) { lConvexVertList.Add(lConvexMeshDatas[c].MeshData.PosVertices[v] + lDeltaPos); } for (int f = 0; f < lConvexMeshDatas[c].MeshData.FaceInfos.Length; f++) { FaceInfo lInfo = lConvexMeshDatas[c].MeshData.FaceInfos[f]; for (int fi = 0; fi < lInfo.Indices.Length; fi++) { lInfo.Indices[fi] += lIndexShift; } lFaceList.Add(lInfo); } lIndexShift += lVertCount; } Vector3 lMin, lMax; GetMinMax(lConvexVertList.ToArray(), out lMin, out lMax); Vector3 lSize = lMax - lMin; Vector3 lMidPoint = lMin + lSize * 0.5f; for (int v = 0; v < lConvexVertList.Count; v++) { lConvexVertList[v] -= lMidPoint; } UMeshData lConvexData = new UMeshData(); lConvexData.PosVertices = lConvexData.UVVertices = lConvexVertList.ToArray(); lConvexData.MeshFaceInfos = new FaceInfo[1][]; lConvexData.MeshFaceInfos[0] = lFaceList.ToArray(); if (lEntDef.HasConvexCollider && lConvexMeshDatas.Count > 0) { Mesh[] lConvexMesh = UMeshCreator.ConvertToMeshes(lConvexData); //if (!AssetDatabase.IsValidFolder("Assets/" + s_Settings.MapFile.name)) //AssetDatabase.CreateFolder("Assets", s_Settings.MapFile.name); //AssetDatabase.CreateAsset(lConvexMesh[0], "Assets/" + s_Settings.MapFile.name + "/OriginalMesh.asset"); MeshCollider lMCollider = lUEnt.gameObject.AddComponent <MeshCollider>(); lMCollider.sharedMesh = lConvexMesh[0]; lMCollider.convex = true; lMCollider.isTrigger = lEntDef.IsConvexTrigger; //if (s_Settings.SaveLevelAsAsset) //AssetDatabase.CreateAsset(lConvexMesh[0], GetAssetPath(lEntGO.name, "CONVEX", lConvexMesh[0].name)); } if (lQEnt.Classname == "volume_enemy_spawn") { bool lWhat = true; } lUEnt.Extents = new Extents3D(lMidPoint, lSize); lUEnt.SetupEntity(lQEnt); Vector3 lValue; if (lUEnt.GetValue("origin", out lValue)) { lUEnt.transform.position = lValue; } else if (lBrushes.Count > 0) { for (int b = 0; b < lBrushes.Count; b++) { lBrushes[b].transform.localPosition = lBrushes[b].transform.position - lMidPoint; } lUEnt.transform.position = lMidPoint; } } } Vector3 lAllMin, lAllMax; GetMinMax(lAllVerts.ToArray(), out lAllMin, out lAllMax); Vector3 lAllSize = lAllMax - lAllMin; Vector3 lAllCenter = lAllMin + lAllSize * 0.5f; lQMap.Extents = new Extents3D(lAllCenter, lAllSize); //var lSO = new SerializedObject(lLevelObject); //if (lSO.ApplyModifiedProperties()) //{ // bool lBreakpoint = false; //} //if (s_Settings.SaveLevelAsAsset) //{ bool lSuccess; //for (int i = 0; i < s_MaterialList.Count; i++) //AssetDatabase.CreateAsset(s_MaterialList[i], "Assets/" + s_Settings.MapFile.name + "_MAT " + i + ".asset"); //PrefabUtility.SaveAsPrefabAsset(lLevelObject, "Assets/" + s_Settings.MapFile.name + ".prefab", out lSuccess); //AssetDatabase.Refresh(); //AssetDatabase.SaveAssets(); //} //if (EditorGUI.EndChangeCheck()) //{ // bool lBreakpoint = false; //} #if UNITY_EDITOR EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); #endif }
public UMeshData GetMeshInformation(Vector3 lPositionDelta) { List <Vector3> lPoints = new List <Vector3>(V.Length); List <int> lVMap = new List <int>(V.Length); for (int i = 0; i < V.Length; i++) { lVMap.Add(-1); } for (int i = 0; i < V.Length; i++) { if (V[i].Visible) { lVMap[i] = lPoints.Count; lPoints.Add(V[i].Position); } } int[] lFaces = GetOrderedFaces(); for (int i = 0; i < lFaces.Length;) { int lNumIndices = lFaces[i]; i++; for (int j = 0; j < lNumIndices; j++) { lFaces[i] = lVMap[lFaces[i]]; i++; } } int lFaceCount = 0; for (int i = 0; i < F.Length; i++) { if (F[i].Visible) { lFaceCount++; } } FaceInfo[] lFaceInfos = new FaceInfo[lFaceCount]; int lFaceIndex = 0; int lVisibleFaceCounter = 0; for (int i = 0; i < F.Length; i++) { if (F[i].Visible) { lFaceInfos[lVisibleFaceCounter] = new FaceInfo(); lFaceInfos[lVisibleFaceCounter].Plane = F[i].Plane; int lIndicesCount = lFaces[lFaceIndex]; int[] lIndices = new int[lIndicesCount]; for (int j = 0; j < lIndicesCount; j++) { lIndices[j] = lFaces[lFaceIndex + j + 1]; } lFaceIndex += lIndicesCount + 1; lFaceInfos[lVisibleFaceCounter].Indices = lIndices; lVisibleFaceCounter++; } } UMeshData lMeshData = new UMeshData(lPoints.ToArray(), lFaceInfos); for (int v = 0; v < lMeshData.UVVertices.Length; v++) { lMeshData.PosVertices[v].x = lMeshData.UVVertices[v].x - lPositionDelta.x; lMeshData.PosVertices[v].y = lMeshData.UVVertices[v].y - lPositionDelta.y; lMeshData.PosVertices[v].z = lMeshData.UVVertices[v].z - lPositionDelta.z; } return(lMeshData); }