using UnityEngine; using UnityEngine.Assertions; using UnityEditor; using System; using System.Linq; using System.Collections; using System.Collections.Generic; using System.IO; namespace VoxelImporter { public class VoxelChunksObjectCore : VoxelBaseCore { public VoxelChunksObjectCore(VoxelBase target) : base(target) { voxelObject = target as VoxelChunksObject; } public VoxelChunksObject voxelObject { get; protected set; } #region Chunk protected IntVector3 GetChunkPosition(IntVector3 position) { IntVector3 cpos = IntVector3.zero; cpos.x = position.x / voxelObject.chunkSize.x; cpos.y = position.y / voxelObject.chunkSize.y; cpos.z = position.z / voxelObject.chunkSize.z; return cpos; } protected class ChunkData { public IntVector3 position; public string name; public VoxelData.ChunkArea area; public List voxels; public Color[] palettes; public VoxelChunksObjectChunk chunkObject; public VoxelData.FaceAreaTable faceAreaTable; public Rect[] atlasRects; public AtlasRectTable atlasRectTable; } protected List chunkDataList; protected override void CreateChunkData() { if (voxelObject.splitMode != VoxelChunksObject.SplitMode.ChunkSize) { if (voxelData.chunkDataList == null) voxelObject.splitMode = VoxelChunksObject.SplitMode.ChunkSize; } if (voxelObject.splitMode == VoxelChunksObject.SplitMode.QubicleMatrix || voxelObject.splitMode == VoxelChunksObject.SplitMode.WorldEditor) { voxelData.chunkTable = new DataTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); var chunkVoxels = new List[voxelData.chunkDataList.Count]; var chunkPalettes = new HashSet[voxelData.chunkDataList.Count]; for (int i = 0; i < voxelData.chunkDataList.Count; i++) { chunkVoxels[i] = new List(); chunkPalettes[i] = new HashSet(); } for (int i = 0; i < voxelData.voxels.Length; i++) { var chunkIndex = voxelData.chunkIndexTable.Get(voxelData.voxels[i].position); //voxel chunkVoxels[chunkIndex].Add(i); //palette chunkPalettes[chunkIndex].Add(voxelData.palettes[voxelData.voxels[i].palette]); // voxelData.chunkTable.Set(voxelData.voxels[i].position, new IntVector3(chunkIndex, int.MinValue, int.MinValue)); } { chunkDataList = new List(chunkVoxels.Length); for (int i = 0; i < chunkVoxels.Length; i++) { chunkDataList.Add(new ChunkData() { position = new IntVector3(i, int.MinValue, int.MinValue), name = string.Format("Chunk({0})", voxelData.chunkDataList[i].name), area = voxelData.chunkDataList[i].area, voxels = chunkVoxels[i], palettes = chunkPalettes[i].ToArray() }); } chunkDataList.Sort((a, b) => string.Compare(voxelData.chunkDataList[a.position.x].name, voxelData.chunkDataList[b.position.x].name)); } } else { voxelData.chunkTable = new DataTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); var chunkVoxels = new DataTable3>(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); var chunkPalettes = new DataTable3>(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); for (int i = 0; i < voxelData.voxels.Length; i++) { var chunkPosition = GetChunkPosition(voxelData.voxels[i].position); //voxel if (!chunkVoxels.Contains(chunkPosition)) chunkVoxels.Set(chunkPosition, new List()); chunkVoxels.Get(chunkPosition).Add(i); //palette if (!chunkPalettes.Contains(chunkPosition)) chunkPalettes.Set(chunkPosition, new HashSet()); chunkPalettes.Get(chunkPosition).Add(voxelData.palettes[voxelData.voxels[i].palette]); // voxelData.chunkTable.Set(voxelData.voxels[i].position, chunkPosition); } { chunkDataList = new List(); chunkVoxels.AllAction((x, y, z, list) => { var pos = new IntVector3(x, y, z); chunkDataList.Add(new ChunkData() { position = pos, name = string.Format("Chunk({0}, {1}, {2})", x, y, z), area = new VoxelData.ChunkArea() { min = pos * voxelObject.chunkSize, max = (pos + IntVector3.one) * voxelObject.chunkSize - IntVector3.one }, voxels = list, palettes = chunkPalettes.Get(pos).ToArray() }); }); chunkDataList.Sort((a, b) => a.position.x != b.position.x ? a.position.x - b.position.x : a.position.y != b.position.y ? a.position.y - b.position.y : a.position.z - b.position.z); } } } public bool removeAllChunk; public void RemoveAllChunk() { removeAllChunk = true; } #endregion #region CreateVoxel public override string GetDefaultPath() { var path = base.GetDefaultPath(); if (voxelObject != null) { if (voxelObject.materials != null) { for (int i = 0; i < voxelObject.materials.Count; i++) { if (AssetDatabase.Contains(voxelObject.materials[i])) { var assetPath = AssetDatabase.GetAssetPath(voxelObject.materials[i]); if (!string.IsNullOrEmpty(assetPath)) { path = Path.GetDirectoryName(assetPath); } } } } if (voxelObject.atlasTexture != null && AssetDatabase.Contains(voxelObject.atlasTexture)) { var assetPath = AssetDatabase.GetAssetPath(voxelObject.atlasTexture); if (!string.IsNullOrEmpty(assetPath)) { path = Path.GetDirectoryName(assetPath); } } } return path; } #endregion #region CreateMesh protected override bool IsCombineVoxelFace(IntVector3 basePos, IntVector3 combinePos, VoxelBase.Face face) { if (!base.IsCombineVoxelFace(basePos, combinePos, face)) return false; return voxelData.chunkTable.Get(basePos) == voxelData.chunkTable.Get(combinePos); } protected override bool IsHiddenVoxelFace(IntVector3 basePos, VoxelBase.Face faceFlag) { if (voxelObject.createContactChunkFaces) { Assert.IsTrue(faceFlag == VoxelBase.Face.forward || faceFlag == VoxelBase.Face.up || faceFlag == VoxelBase.Face.right || faceFlag == VoxelBase.Face.left || faceFlag == VoxelBase.Face.down || faceFlag == VoxelBase.Face.back); IntVector3 combinePos = basePos; { if (faceFlag == VoxelBase.Face.forward) combinePos.z++; if (faceFlag == VoxelBase.Face.up) combinePos.y++; if (faceFlag == VoxelBase.Face.right) combinePos.x++; if (faceFlag == VoxelBase.Face.left) combinePos.x--; if (faceFlag == VoxelBase.Face.down) combinePos.y--; if (faceFlag == VoxelBase.Face.back) combinePos.z--; } return voxelData.chunkTable.Get(basePos) == voxelData.chunkTable.Get(combinePos); } else { return base.IsHiddenVoxelFace(basePos, faceFlag); } } protected override void CreateMeshBefore() { base.CreateMeshBefore(); #region RemoveChunk voxelObject.UpdateChunks(); var chunkObjects = voxelObject.chunks; { bool chunkObjectsUpdate = false; bool[] enableTale = new bool[chunkObjects.Length]; if (!removeAllChunk) { for (int i = 0; i < chunkDataList.Count; i++) { for (int j = 0; j < chunkObjects.Length; j++) { if (chunkDataList[i].position == chunkObjects[j].position) { enableTale[j] = true; break; } } } } else { removeAllChunk = false; } for (int i = 0; i < enableTale.Length; i++) { if (!enableTale[i]) { var go = chunkObjects[i].gameObject; while (go.transform.childCount > 0) { Undo.SetTransformParent(go.transform.GetChild(0), voxelObject.transform, "Remove Chunk"); } Undo.DestroyObjectImmediate(go); chunkObjectsUpdate = true; } } if (chunkObjectsUpdate) { voxelObject.UpdateChunks(); chunkObjects = voxelObject.chunks; } } #endregion #region AddChunk int chunkCount = 0; { bool chunkObjectsUpdate = false; for (int i = 0; i < chunkDataList.Count; i++) { GameObject chunkObject = null; for (int j = 0; j < chunkObjects.Length; j++) { if (chunkDataList[i].position == chunkObjects[j].position) { chunkObject = chunkObjects[j].gameObject; break; } } if (chunkObject == null) { chunkObject = new GameObject(chunkDataList[i].name); Undo.RegisterCreatedObjectUndo(chunkObject, "Create Chunk"); Undo.SetTransformParent(chunkObject.transform, voxelObject.transform, "Create Chunk"); GameObjectUtility.SetStaticEditorFlags(chunkObject, GameObjectUtility.GetStaticEditorFlags(voxelObject.gameObject)); chunkObject.transform.localPosition = Vector3.Scale(voxelObject.localOffset + chunkDataList[i].area.centerf, voxelObject.importScale); chunkObject.transform.localRotation = Quaternion.identity; chunkObject.transform.localScale = Vector3.one; chunkObject.layer = voxelObject.gameObject.layer; chunkObject.tag = voxelObject.gameObject.tag; chunkObjectsUpdate = true; } VoxelChunksObjectChunk controller = chunkObject.GetComponent(); if (controller == null) controller = Undo.AddComponent(chunkObject); controller.position = chunkDataList[i].position; controller.chunkName = chunkDataList[i].name; controller.basicOffset = Vector3.Scale(voxelObject.localOffset + chunkDataList[i].area.centerf, voxelObject.importScale); chunkCount++; } if (chunkObjectsUpdate) { voxelObject.UpdateChunks(); chunkObjects = voxelObject.chunks; } } #endregion #region SortChunk { List objList = new List(); var childCount = voxelObject.transform.childCount; for (int i = 0; i < childCount; i++) { objList.Add(voxelObject.transform.GetChild(i)); } objList.Sort((obj1, obj2) => string.Compare(obj1.name, obj2.name)); for (int i = 0; i < objList.Count; i++) { objList[i].SetSiblingIndex(childCount - 1); } voxelObject.UpdateChunks(); chunkObjects = voxelObject.chunks; } #endregion #region UpdateChunk for (int i = 0; i < chunkObjects.Length; i++) { for (int j = 0; j < chunkDataList.Count; j++) { if (chunkObjects[i].position == chunkDataList[j].position) { chunkDataList[j].chunkObject = chunkObjects[i]; break; } } } #endregion } protected override bool CreateMesh() { base.CreateMesh(); #region ProgressBar const float MaxProgressCount = 6f; float ProgressCount = 0; Action DisplayProgressBar = (info) => { if (voxelData.voxels.Length > 10000) EditorUtility.DisplayProgressBar("Create Mesh...", string.Format("{0} / {1}", ProgressCount, MaxProgressCount), (ProgressCount++ / MaxProgressCount)); }; #endregion DisplayProgressBar(""); #region Disable { if (voxelObject.disableData == null) voxelObject.disableData = new DisableData(); #region Erase { List removeList = new List(); voxelObject.disableData.AllAction((pos, face) => { if (voxelData.VoxelTableContains(pos) < 0) { removeList.Add(pos); } }); for (int j = 0; j < removeList.Count; j++) { voxelObject.disableData.RemoveDisable(removeList[j]); } } #endregion } #endregion DisplayProgressBar(""); #region Material { if (voxelObject.materialData == null) voxelObject.materialData = new List(); if (voxelObject.materialData.Count == 0) voxelObject.materialData.Add(null); for (int i = 0; i < voxelObject.materialData.Count; i++) { if (voxelObject.materialData[i] == null) voxelObject.materialData[i] = new MaterialData(); } #region Erase for (int i = 0; i < voxelObject.materialData.Count; i++) { List removeList = new List(); voxelObject.materialData[i].AllAction((pos) => { if (voxelData.VoxelTableContains(pos) < 0) { removeList.Add(pos); } }); for (int j = 0; j < removeList.Count; j++) { voxelObject.materialData[i].RemoveMaterial(removeList[j]); } } #endregion if (voxelObject.materials == null) voxelObject.materials = new List(); if (voxelObject.materials.Count < voxelObject.materialData.Count) { for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++) voxelObject.materials.Add(null); } else if (voxelObject.materials.Count > voxelObject.materialData.Count) { voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count); } } voxelObject.CreateMaterialIndexTable(); #endregion CalcDataCreate(voxelData.voxels); #region CreateFaceAreaTable { for (int i = 0; i < chunkDataList.Count; i++) { var voxels = new VoxelData.Voxel[chunkDataList[i].voxels.Count]; for (int j = 0; j < chunkDataList[i].voxels.Count; j++) { voxels[j] = voxelData.voxels[chunkDataList[i].voxels[j]]; } chunkDataList[i].faceAreaTable = CreateFaceArea(voxels); // if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual) { var paletteTable = new int[voxelData.palettes.Length]; for (int j = 0; j < voxelData.palettes.Length; j++) { int newIndex = -1; for (int k = 0; k < chunkDataList[i].palettes.Length; k++) { if (chunkDataList[i].palettes[k] == voxelData.palettes[j]) { newIndex = k; break; } } paletteTable[j] = newIndex; } chunkDataList[i].faceAreaTable.ReplacePalette(paletteTable); } } } #endregion #region CreateTexture if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine) { #region Combine var tmpFaceAreaTable = new VoxelData.FaceAreaTable(); for (int i = 0; i < chunkDataList.Count; i++) { tmpFaceAreaTable.Merge(chunkDataList[i].faceAreaTable); } { var atlasTextureTmp = voxelObject.atlasTexture; if (chunkDataList != null && chunkDataList.Count > 0) { if (!CreateTexture(tmpFaceAreaTable, voxelData.palettes, ref chunkDataList[0].atlasRectTable, ref atlasTextureTmp, ref chunkDataList[0].atlasRects)) { EditorUtility.ClearProgressBar(); return false; } } else { AtlasRectTable atlasRectTable = null; Rect[] atlasRects = null; if (!CreateTexture(tmpFaceAreaTable, voxelData.palettes, ref atlasRectTable, ref atlasTextureTmp, ref atlasRects)) { EditorUtility.ClearProgressBar(); return false; } } voxelObject.atlasTexture = atlasTextureTmp; { if (voxelObject.materialData == null) voxelObject.materialData = new List(); if (voxelObject.materialData.Count == 0) voxelObject.materialData.Add(null); for (int i = 0; i < voxelObject.materialData.Count; i++) { if (voxelObject.materialData[i] == null) voxelObject.materialData[i] = new MaterialData(); } if (voxelObject.materials == null) voxelObject.materials = new List(); if (voxelObject.materials.Count < voxelObject.materialData.Count) { for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++) voxelObject.materials.Add(null); } else if (voxelObject.materials.Count > voxelObject.materialData.Count) { voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count); } for (int i = 0; i < voxelObject.materials.Count; i++) { if (voxelObject.materials[i] == null) voxelObject.materials[i] = new Material(Shader.Find("Standard")); if (!AssetDatabase.Contains(voxelObject.materials[i])) { AddObjectToPrefabAsset(voxelObject.materials[i], "mat", i); } } if (!AssetDatabase.Contains(voxelObject.atlasTexture)) { AddObjectToPrefabAsset(voxelObject.atlasTexture, "tex"); } } for (int i = 0; i < chunkDataList.Count; i++) { chunkDataList[i].atlasRects = chunkDataList[0].atlasRects; chunkDataList[i].atlasRectTable = chunkDataList[0].atlasRectTable; chunkDataList[i].chunkObject.materials = null; chunkDataList[i].chunkObject.atlasTexture = null; } } #endregion } else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual) { #region Individual if (voxelObject.materialData == null) voxelObject.materialData = new List(); if (voxelObject.materialData.Count == 0) voxelObject.materialData.Add(null); for (int i = 0; i < voxelObject.materialData.Count; i++) { if (voxelObject.materialData[i] == null) voxelObject.materialData[i] = new MaterialData(); } voxelObject.materials = null; voxelObject.atlasTexture = null; for (int c = 0; c < chunkDataList.Count; c++) { var atlasTextureTmp = chunkDataList[c].chunkObject.atlasTexture; if (!CreateTexture(chunkDataList[c].faceAreaTable, chunkDataList[c].palettes, ref chunkDataList[c].atlasRectTable, ref atlasTextureTmp, ref chunkDataList[c].atlasRects)) { EditorUtility.ClearProgressBar(); return false; } chunkDataList[c].chunkObject.atlasTexture = atlasTextureTmp; { if (chunkDataList[c].chunkObject.materials == null) chunkDataList[c].chunkObject.materials = new List(); if (chunkDataList[c].chunkObject.materials.Count < voxelObject.materialData.Count) { for (int i = chunkDataList[c].chunkObject.materials.Count; i < voxelObject.materialData.Count; i++) chunkDataList[c].chunkObject.materials.Add(null); } else if (chunkDataList[c].chunkObject.materials.Count > voxelObject.materialData.Count) { chunkDataList[c].chunkObject.materials.RemoveRange(voxelObject.materialData.Count, chunkDataList[c].chunkObject.materials.Count - voxelObject.materialData.Count); } for (int i = 0; i < chunkDataList[c].chunkObject.materials.Count; i++) { if (chunkDataList[c].chunkObject.materials[i] == null) chunkDataList[c].chunkObject.materials[i] = new Material(Shader.Find("Standard")); if (!AssetDatabase.Contains(chunkDataList[c].chunkObject.materials[i])) { AddObjectToPrefabAsset(chunkDataList[c].chunkObject.materials[i], string.Format("{0}_mat", chunkDataList[c].chunkObject.name), i); } } if (!AssetDatabase.Contains(chunkDataList[c].chunkObject.atlasTexture)) { AddObjectToPrefabAsset(chunkDataList[c].chunkObject.atlasTexture, string.Format("{0}_tex", chunkDataList[c].chunkObject.name)); } } } #endregion } else { Assert.IsTrue(false); } #endregion #region CreateMesh DisplayProgressBar(""); { if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine) { #region Combine if (voxelObject.importMode == VoxelBase.ImportMode.LowPoly) { int forward = 0; int up = 0; int right = 0; int left = 0; int down = 0; int back = 0; for (int i = 0; i < chunkDataList.Count; i++) { AtlasRectTable atlasRectTable = new AtlasRectTable(); { atlasRectTable.forward = chunkDataList[i].atlasRectTable.forward.GetRange(forward, chunkDataList[i].faceAreaTable.forward.Count); forward += chunkDataList[i].faceAreaTable.forward.Count; atlasRectTable.up = chunkDataList[i].atlasRectTable.up.GetRange(up, chunkDataList[i].faceAreaTable.up.Count); up += chunkDataList[i].faceAreaTable.up.Count; atlasRectTable.right = chunkDataList[i].atlasRectTable.right.GetRange(right, chunkDataList[i].faceAreaTable.right.Count); right += chunkDataList[i].faceAreaTable.right.Count; atlasRectTable.left = chunkDataList[i].atlasRectTable.left.GetRange(left, chunkDataList[i].faceAreaTable.left.Count); left += chunkDataList[i].faceAreaTable.left.Count; atlasRectTable.down = chunkDataList[i].atlasRectTable.down.GetRange(down, chunkDataList[i].faceAreaTable.down.Count); down += chunkDataList[i].faceAreaTable.down.Count; atlasRectTable.back = chunkDataList[i].atlasRectTable.back.GetRange(back, chunkDataList[i].faceAreaTable.back.Count); back += chunkDataList[i].faceAreaTable.back.Count; } chunkDataList[i].chunkObject.mesh = CreateMeshOnly(chunkDataList[i].chunkObject.mesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, chunkDataList[i].atlasRects, atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes); if (!AssetDatabase.Contains(chunkDataList[i].chunkObject.mesh)) { AddObjectToPrefabAsset(chunkDataList[i].chunkObject.mesh, string.Format("{0}_mesh", chunkDataList[i].chunkObject.name)); } } } else { for (int i = 0; i < chunkDataList.Count; i++) { chunkDataList[i].chunkObject.mesh = CreateMeshOnly(chunkDataList[i].chunkObject.mesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, chunkDataList[i].atlasRects, chunkDataList[i].atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes); if (!AssetDatabase.Contains(chunkDataList[i].chunkObject.mesh)) { AddObjectToPrefabAsset(chunkDataList[i].chunkObject.mesh, string.Format("{0}_mesh", chunkDataList[i].chunkObject.name)); } } } #endregion } else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual) { #region Individual for (int i = 0; i < chunkDataList.Count; i++) { chunkDataList[i].chunkObject.mesh = CreateMeshOnly(chunkDataList[i].chunkObject.mesh, chunkDataList[i].faceAreaTable, chunkDataList[i].chunkObject.atlasTexture, chunkDataList[i].atlasRects, chunkDataList[i].atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes); if (!AssetDatabase.Contains(chunkDataList[i].chunkObject.mesh)) { AddObjectToPrefabAsset(chunkDataList[i].chunkObject.mesh, string.Format("{0}_mesh", chunkDataList[i].chunkObject.name)); } } #endregion } else { Assert.IsTrue(false); } } #endregion DisplayProgressBar(""); if (voxelBase.generateLightmapUVs) { var param = voxelBase.GetLightmapParam(); for (int i = 0; i < chunkDataList.Count; i++) { if (chunkDataList[i].chunkObject.mesh.uv.Length > 0) Unwrapping.GenerateSecondaryUVSet(chunkDataList[i].chunkObject.mesh, param); } } if (voxelBase.generateTangents) { for (int i = 0; i < chunkDataList.Count; i++) { chunkDataList[i].chunkObject.mesh.RecalculateTangents(); } } DisplayProgressBar(""); SetRendererCompornent(); RefreshCheckerSave(); EditorUtility.ClearProgressBar(); return true; } protected override void CreateMeshAfter() { chunkDataList = null; base.CreateMeshAfter(); } public override void SetRendererCompornent() { var chunkObjects = voxelObject.chunks; if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine) { if (voxelBase.updateMaterialTexture) { if (voxelObject.materials != null) { for (int i = 0; i < voxelObject.materials.Count; i++) { if (voxelObject.materials[i] == null) continue; Undo.RecordObject(voxelObject.materials[i], "Inspector"); voxelObject.materials[i].mainTexture = voxelObject.atlasTexture; } } } for (int i = 0; i < chunkObjects.Length; i++) { if (chunkObjects[i] == null) continue; { var meshFilter = chunkObjects[i].GetComponent(); if (meshFilter != null) { Undo.RecordObject(meshFilter, "Inspector"); meshFilter.sharedMesh = chunkObjects[i].mesh; } } if (voxelBase.updateMeshRendererMaterials) { var renderer = chunkObjects[i].GetComponent(); Undo.RecordObject(renderer, "Inspector"); if (voxelObject.materials != null) { Material[] tmps = new Material[chunkObjects[i].materialIndexes.Count]; for (int j = 0; j < chunkObjects[i].materialIndexes.Count; j++) { tmps[j] = voxelObject.materials[chunkObjects[i].materialIndexes[j]]; } renderer.sharedMaterials = tmps; } else { renderer.sharedMaterial = null; } } if (voxelBase.loadFromVoxelFile && voxelBase.materialData != null) { if (voxelObject.materials != null && voxelObject.materials.Count == voxelBase.materialData.Count) { for (int j = 0; j < voxelObject.materials.Count; j++) { Undo.RecordObject(voxelObject.materials[j], "Inspector"); SetMaterialData(voxelObject.materials[j], voxelBase.materialData[j]); } } } } } else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual) { if (voxelBase.updateMaterialTexture) { for (int i = 0; i < chunkObjects.Length; i++) { if (chunkObjects[i].materials != null) { for (int j = 0; j < chunkObjects[i].materials.Count; j++) { if (chunkObjects[i].materials[j] == null) continue; Undo.RecordObject(chunkObjects[i].materials[j], "Inspector"); chunkObjects[i].materials[j].mainTexture = chunkObjects[i].atlasTexture; } } } } for (int i = 0; i < chunkObjects.Length; i++) { { var meshFilter = chunkObjects[i].GetComponent(); if (meshFilter != null) { Undo.RecordObject(meshFilter, "Inspector"); meshFilter.sharedMesh = chunkObjects[i].mesh; } } if (voxelBase.updateMeshRendererMaterials) { var renderer = chunkObjects[i].GetComponent(); Undo.RecordObject(renderer, "Inspector"); if (chunkObjects[i].materials != null) { Material[] tmps = new Material[chunkObjects[i].materialIndexes.Count]; for (int j = 0; j < chunkObjects[i].materialIndexes.Count; j++) { tmps[j] = chunkObjects[i].materials[chunkObjects[i].materialIndexes[j]]; } renderer.sharedMaterials = tmps; } else { renderer.sharedMaterial = null; } } if (voxelBase.loadFromVoxelFile && voxelBase.materialData != null) { if (chunkObjects[i].materials != null && chunkObjects[i].materials.Count == voxelBase.materialData.Count) { for (int j = 0; j < chunkObjects[i].materials.Count; j++) { Undo.RecordObject(chunkObjects[i].materials[j], "Inspector"); SetMaterialData(chunkObjects[i].materials[j], voxelBase.materialData[j]); } } } } } else { Assert.IsTrue(false); } } public override Mesh[] Edit_CreateMesh(List voxels, List dstList = null, bool combine = true) { return new Mesh[1] { Edit_CreateMeshOnly(voxels, null, dstList, combine) }; } public Mesh[] Edit_CreateMesh(List[] chunkVoxels, List[] chunkDstList = null, bool combine = true) { Assert.IsTrue(chunkVoxels.Length == chunkDataList.Count); var meshs = new Mesh[chunkVoxels.Length]; for (int i = 0; i < chunkVoxels.Length; i++) { meshs[i] = Edit_CreateMeshOnly(chunkVoxels[i], chunkDataList[i].atlasRects, chunkDstList[i], combine); } return meshs; } #endregion #region Edit public override void SetSelectedWireframeHidden(bool hidden) { if (voxelObject == null) return; var chunkObjects = voxelObject.chunks; for (int i = 0; i < chunkObjects.Length; i++) { if (chunkObjects[i] == null) continue; var renderer = chunkObjects[i].GetComponent(); if (renderer != null) { EditorUtility.SetSelectedRenderState(renderer, hidden ? EditorSelectedRenderState.Hidden : EditorSelectedRenderState.Wireframe | EditorSelectedRenderState.Highlight); } } } #endregion #region Export protected override void ExportDaeFile_AddTransform(List transforms) { base.ExportDaeFile_AddTransform(transforms); for (int i = 0; i < voxelObject.chunks.Length; i++) { transforms.Add(voxelObject.chunks[i].transform); } } #endregion #region Undo protected override void RefreshCheckerCreate() { voxelObject.refreshChecker = new VoxelChunksObject.RefreshCheckerChunk(voxelObject); } #endregion } }