public override void GenerateOnly()
        {
            if (voxelObject == null || voxelObjectCore.voxelData == null)
            {
                return;
            }
            var voxelData = voxelObjectCore.voxelData;

            //BasicCube
            Vector3        cubeCenter;
            List <Vector3> cubeVertices;
            List <Vector3> cubeNormals;
            List <int>     cubeTriangles;

            CreateBasicCube(out cubeCenter, out cubeVertices, out cubeNormals, out cubeTriangles);

            #region Voxels
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector3> normals   = new List <Vector3>();
            List <Color>   colors    = new List <Color>();
            List <Vector4> tangents  = new List <Vector4>();
            List <int>[]   triangles = new List <int> [voxelBase.materialData.Count];
            for (int i = 0; i < triangles.Length; i++)
            {
                triangles[i] = new List <int>();
            }

            #region Mesh
            Func <VoxelObjectExplosion.MeshData, VoxelObjectExplosion.MeshData> CreateMesh = (data) =>
            {
                if (data == null)
                {
                    data = new VoxelObjectExplosion.MeshData();
                }
                if (data.mesh == null)
                {
                    data.mesh = new Mesh();
                }
                else
                {
                    data.mesh.Clear(false);
                    data.mesh.ClearBlendShapes();
                }
                data.materialIndexes.Clear();
#if UNITY_2017_3_OR_NEWER
                data.mesh.indexFormat = vertices.Count > 65000 ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16;
#endif
                data.mesh.vertices = vertices.ToArray();
                data.mesh.normals  = normals.ToArray();
                data.mesh.colors   = colors.ToArray();
                data.mesh.tangents = tangents.ToArray();
                {
                    int materialCount = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            materialCount++;
                        }
                    }
                    data.mesh.subMeshCount = materialCount;
                    int submesh = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            data.materialIndexes.Add(i);
                            data.mesh.SetTriangles(triangles[i].ToArray(), submesh++);
                        }
                    }
                }
                data.mesh.RecalculateBounds();
                {
                    var bounds = data.mesh.bounds;
                    bounds.min      -= Vector3.one * explosionBase.edit_velocityMax;
                    bounds.max      += Vector3.one * explosionBase.edit_velocityMax;
                    data.mesh.bounds = bounds;
                }
                vertices.Clear();
                normals.Clear();
                colors.Clear();
                tangents.Clear();
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    triangles[i].Clear();
                }
                return(data);
            };
            #endregion

            {
                int meshIndex = 0;
                Action <int, int> AddVertex = (mat, index) =>
                {
                    if (explosionBase.edit_birthRate < 1f)
                    {
                        if (UnityEngine.Random.value >= explosionBase.edit_birthRate)
                        {
                            return;
                        }
                    }
                    if (explosionBase.edit_visibleOnly)
                    {
                        if (!voxelObjectCore.IsVoxelVisible(voxelData.voxels[index].position))
                        {
                            return;
                        }
                    }

#if !UNITY_2017_3_OR_NEWER
                    if (vertices.Count + cubeVertices.Count >= 65000)
                    {
                        for (int i = explosionObject.meshes.Count; i <= meshIndex; i++)
                        {
                            explosionObject.meshes.Add(null);
                        }
                        explosionObject.meshes[meshIndex] = CreateMesh(explosionObject.meshes[meshIndex]);
                        if (!AssetDatabase.Contains(explosionObject.meshes[meshIndex].mesh))
                        {
                            voxelBaseCore.AddObjectToPrefabAsset(explosionObject.meshes[meshIndex].mesh, "explosion_mesh", meshIndex);
                        }
                        meshIndex++;
                    }
#endif

                    var color   = voxelData.palettes[voxelData.voxels[index].palette];
                    var vOffset = vertices.Count;
                    for (int i = 0; i < cubeVertices.Count; i++)
                    {
                        var pos = cubeVertices[i];
                        pos.x += voxelData.voxels[index].position.x * voxelBase.importScale.x;
                        pos.y += voxelData.voxels[index].position.y * voxelBase.importScale.y;
                        pos.z += voxelData.voxels[index].position.z * voxelBase.importScale.z;
                        vertices.Add(pos);
                    }
                    normals.AddRange(cubeNormals);
                    for (int j = 0; j < cubeTriangles.Count; j++)
                    {
                        triangles[mat].Add(vOffset + cubeTriangles[j]);
                    }
                    for (int j = 0; j < cubeVertices.Count; j++)
                    {
                        colors.Add(color);
                    }
                    {
                        Vector3 center = new Vector3
                                         (
                            center.x = cubeCenter.x + voxelData.voxels[index].position.x * voxelBase.importScale.x,
                            center.y = cubeCenter.y + voxelData.voxels[index].position.y * voxelBase.importScale.y,
                            center.z = cubeCenter.z + voxelData.voxels[index].position.z * voxelBase.importScale.z
                                         );
                        var velocity = UnityEngine.Random.Range(explosionBase.edit_velocityMin, explosionBase.edit_velocityMax);
                        for (int j = 0; j < cubeVertices.Count; j++)
                        {
                            tangents.Add(new Vector4(center.x - vertices[vOffset + j].x, center.y - vertices[vOffset + j].y, center.z - vertices[vOffset + j].z, velocity));
                        }
                    }
                };

                if (explosionObject.meshes == null)
                {
                    explosionObject.meshes = new List <VoxelObjectExplosion.MeshData>();
                }
                FlagTable3 doneTable = new FlagTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z);
                for (int i = 1; i < voxelBase.materialData.Count; i++)
                {
                    voxelBase.materialData[i].AllAction((pos) =>
                    {
                        doneTable.Set(pos, true);
                        var index = voxelData.VoxelTableContains(pos);
                        if (index < 0)
                        {
                            return;
                        }
                        AddVertex(i, index);
                    });
                }
                for (int index = 0; index < voxelData.voxels.Length; index++)
                {
                    if (doneTable.Get(voxelData.voxels[index].position))
                    {
                        continue;
                    }
                    AddVertex(0, index);
                }
                if (vertices.Count > 0)
                {
                    for (int i = explosionObject.meshes.Count; i <= meshIndex; i++)
                    {
                        explosionObject.meshes.Add(null);
                    }
                    explosionObject.meshes[meshIndex] = CreateMesh(explosionObject.meshes[meshIndex]);
                    if (!AssetDatabase.Contains(explosionObject.meshes[meshIndex].mesh))
                    {
                        voxelBaseCore.AddObjectToPrefabAsset(explosionObject.meshes[meshIndex].mesh, "explosion_mesh", meshIndex);
                    }
                    meshIndex++;
                }
                explosionObject.meshes.RemoveRange(meshIndex, explosionObject.meshes.Count - meshIndex);
            }
            #endregion

            #region Material
            if (explosionObject.materials == null)
            {
                explosionObject.materials = new List <Material>();
            }
            if (explosionObject.materials.Count < voxelBase.materialData.Count)
            {
                for (int i = explosionObject.materials.Count; i < voxelBase.materialData.Count; i++)
                {
                    explosionObject.materials.Add(null);
                }
            }
            else if (explosionObject.materials.Count > voxelBase.materialData.Count)
            {
                explosionObject.materials.RemoveRange(voxelBase.materialData.Count, explosionObject.materials.Count - voxelBase.materialData.Count);
            }
            for (int i = 0; i < voxelBase.materialData.Count; i++)
            {
                if (!voxelBase.materialIndexes.Contains(i))
                {
                    if (explosionObject.materials[i] != null)
                    {
                        explosionObject.materials[i] = null;
                        voxelBaseCore.DestroyUnusedObjectInPrefabObject();
                    }
                    continue;
                }
                if (explosionObject.materials[i] == null)
                {
                    explosionObject.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent));
                }
                else
                {
                    explosionObject.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent);
                }
                if (!AssetDatabase.Contains(explosionObject.materials[i]))
                {
                    explosionObject.materials[i].name = explosionObject.materials[i].shader.name;
                }
                if (!AssetDatabase.Contains(explosionObject.materials[i]))
                {
                    voxelBaseCore.AddObjectToPrefabAsset(explosionObject.materials[i], "explosion_mat", i);
                }
            }
            #endregion
        }
        public override void GenerateOnly()
        {
            if (voxelObject == null || voxelObjectCore.voxelData == null)
            {
                return;
            }
            var voxelData = voxelObjectCore.voxelData;

            //BasicCube
            Vector3        cubeCenter;
            List <Vector3> cubeVertices;
            List <Vector3> cubeNormals;
            List <int>     cubeTriangles;

            CreateBasicCube(out cubeCenter, out cubeVertices, out cubeNormals, out cubeTriangles);

            #region Voxels
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector3> normals   = new List <Vector3>();
            List <Color>   colors    = new List <Color>();
            List <Vector4> tangents  = new List <Vector4>();
            List <int>[]   triangles = new List <int> [voxelBase.materialData.Count];
            for (int i = 0; i < triangles.Length; i++)
            {
                triangles[i] = new List <int>();
            }

            #region Mesh
            Func <VoxelBaseExplosion.MeshData, VoxelBaseExplosion.MeshData> CreateMesh = (data) =>
            {
                if (data == null)
                {
                    data = new VoxelObjectExplosion.MeshData();
                }
                if (data.mesh == null)
                {
                    data.mesh = new Mesh();
                }
                else
                {
                    data.mesh.Clear(false);
                    data.mesh.ClearBlendShapes();
                }
                data.materialIndexes.Clear();
#if UNITY_2017_3_OR_NEWER
                data.mesh.indexFormat = vertices.Count > 65000 ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16;
#endif
                data.mesh.vertices = vertices.ToArray();
                data.mesh.normals  = normals.ToArray();
                data.mesh.colors   = colors.ToArray();
                data.mesh.tangents = tangents.ToArray();
                {
                    int materialCount = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            materialCount++;
                        }
                    }
                    data.mesh.subMeshCount = materialCount;
                    int submesh = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            data.materialIndexes.Add(i);
                            data.mesh.SetTriangles(triangles[i].ToArray(), submesh++);
                        }
                    }
                }
                data.mesh.RecalculateBounds();
                {
                    var bounds = data.mesh.bounds;
                    bounds.min      -= Vector3.one * explosionBase.edit_velocityMax;
                    bounds.max      += Vector3.one * explosionBase.edit_velocityMax;
                    data.mesh.bounds = bounds;
                }
                vertices.Clear();
                normals.Clear();
                colors.Clear();
                tangents.Clear();
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    triangles[i].Clear();
                }
                return(data);
            };
            #endregion

            {
                var        chunkObjects = voxelObject.chunks;
                FlagTable3 doneTable    = new FlagTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z);
                for (int chunkIndex = 0; chunkIndex < chunkObjects.Length; chunkIndex++)
                {
                    var chunkObject = chunkObjects[chunkIndex];
                    if (chunkObject == null)
                    {
                        explosionObject.chunksExplosion[chunkIndex] = null;
                        continue;
                    }
                    var explosionChunk = explosionObject.chunksExplosion[chunkIndex] = chunkObject.gameObject.GetComponent <VoxelChunksObjectChunkExplosion>();
                    if (explosionChunk == null)
                    {
                        explosionChunk = explosionObject.chunksExplosion[chunkIndex] = Undo.AddComponent <VoxelChunksObjectChunkExplosion>(chunkObject.gameObject);
                    }

                    int meshIndex = 0;
                    Action <int, int> AddVertex = (mat, index) =>
                    {
                        if (explosionBase.edit_birthRate < 1f)
                        {
                            if (UnityEngine.Random.value >= explosionBase.edit_birthRate)
                            {
                                return;
                            }
                        }
                        if (explosionBase.edit_visibleOnly)
                        {
                            if (!voxelObjectCore.IsVoxelVisible(voxelData.voxels[index].position))
                            {
                                return;
                            }
                        }

#if !UNITY_2017_3_OR_NEWER
                        if (vertices.Count + cubeVertices.Count >= 65000)
                        {
                            for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++)
                            {
                                explosionChunk.meshes.Add(null);
                            }
                            explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]);
                            {
                                if (voxelBase.legacySubAssetNaming)
                                {
                                    explosionChunk.meshes[meshIndex].mesh.name = string.Format("{0}_explosion_mesh{1}", explosionChunk.name, meshIndex);
                                }
                                else
                                {
                                    explosionChunk.meshes[meshIndex].mesh.name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, meshIndex);
                                }
                            }
                            if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh))
                            {
                                voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh);
                            }
                            meshIndex++;
                        }
#endif

                        var velocity = UnityEngine.Random.Range(explosionBase.edit_velocityMin, explosionBase.edit_velocityMax);
                        var color    = voxelData.palettes[voxelData.voxels[index].palette];
#if UNITY_2018_1_OR_NEWER
                        if (EditorCommon.IsUniversalRenderPipeline() || EditorCommon.IsHighDefinitionRenderPipeline())
                        {
                            color.a = velocity;
                        }
#endif
                        var vOffset = vertices.Count;
                        for (int i = 0; i < cubeVertices.Count; i++)
                        {
                            var pos = cubeVertices[i];
                            pos.x += voxelData.voxels[index].position.x * voxelBase.importScale.x;
                            pos.y += voxelData.voxels[index].position.y * voxelBase.importScale.y;
                            pos.z += voxelData.voxels[index].position.z * voxelBase.importScale.z;
                            vertices.Add(pos);
                        }
                        normals.AddRange(cubeNormals);
                        for (int j = 0; j < cubeTriangles.Count; j++)
                        {
                            triangles[mat].Add(vOffset + cubeTriangles[j]);
                        }
                        for (int j = 0; j < cubeVertices.Count; j++)
                        {
                            colors.Add(color);
                        }
                        {
                            Vector3 center = new Vector3
                                             (
                                center.x = cubeCenter.x + voxelData.voxels[index].position.x * voxelBase.importScale.x,
                                center.y = cubeCenter.y + voxelData.voxels[index].position.y * voxelBase.importScale.y,
                                center.z = cubeCenter.z + voxelData.voxels[index].position.z * voxelBase.importScale.z
                                             );
                            for (int j = 0; j < cubeVertices.Count; j++)
                            {
                                tangents.Add(new Vector4(center.x - vertices[vOffset + j].x, center.y - vertices[vOffset + j].y, center.z - vertices[vOffset + j].z, velocity));
                            }
                        }
                    };

                    if (explosionChunk.meshes == null)
                    {
                        explosionChunk.meshes = new List <VoxelBaseExplosion.MeshData>();
                    }
                    for (int i = 1; i < voxelBase.materialData.Count; i++)
                    {
                        voxelBase.materialData[i].AllAction((pos) =>
                        {
                            if (doneTable.Get(pos))
                            {
                                return;
                            }
                            if (voxelData.chunkTable.Get(pos) != chunkObject.position)
                            {
                                return;
                            }
                            doneTable.Set(pos, true);
                            var index = voxelData.VoxelTableContains(pos);
                            if (index < 0)
                            {
                                return;
                            }
                            AddVertex(i, index);
                        });
                    }
                    for (int index = 0; index < voxelData.voxels.Length; index++)
                    {
                        var pos = voxelData.voxels[index].position;
                        if (doneTable.Get(pos))
                        {
                            continue;
                        }
                        if (voxelData.chunkTable.Get(pos) != chunkObject.position)
                        {
                            continue;
                        }
                        doneTable.Set(pos, true);
                        AddVertex(0, index);
                    }
                    if (vertices.Count > 0)
                    {
                        for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++)
                        {
                            explosionChunk.meshes.Add(null);
                        }
                        explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]);
                        if (!AssetDatabase.IsMainAsset(explosionChunk.meshes[meshIndex].mesh))
                        {
                            if (voxelBase.legacyAssetNaming)
                            {
                                explosionChunk.meshes[meshIndex].mesh.name = string.Format("{0}_explosion_mesh{1}", explosionChunk.name, meshIndex);
                            }
                            else
                            {
                                explosionChunk.meshes[meshIndex].mesh.name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, meshIndex);
                            }
                        }
                        if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh))
                        {
                            voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh);
                        }
                        meshIndex++;
                    }
                    explosionChunk.meshes.RemoveRange(meshIndex, explosionChunk.meshes.Count - meshIndex);

                    explosionChunk.chunkBasicOffset = chunkObject.basicOffset;
                }
            }
            #endregion

            #region Material
            explosionObject.materialMode = voxelObject.materialMode;
            if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine)
            {
                if (explosionObject.materials == null)
                {
                    explosionObject.materials = new List <Material>();
                }
                if (explosionObject.materials.Count < voxelBase.materialData.Count)
                {
                    for (int i = explosionObject.materials.Count; i < voxelBase.materialData.Count; i++)
                    {
                        explosionObject.materials.Add(null);
                    }
                }
                else if (explosionObject.materials.Count > voxelBase.materialData.Count)
                {
                    explosionObject.materials.RemoveRange(voxelBase.materialData.Count, explosionObject.materials.Count - voxelBase.materialData.Count);
                }
                for (int i = 0; i < explosionObject.chunksExplosion.Length; i++)
                {
                    explosionObject.chunksExplosion[i].materials = null;
                }
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    if (!voxelBase.materialIndexes.Contains(i))
                    {
                        if (explosionObject.materials[i] != null)
                        {
                            explosionObject.materials[i] = null;
                            voxelBaseCore.DestroyUnusedObjectInPrefabObject();
                        }
                        continue;
                    }
                    if (explosionObject.materials[i] == null)
                    {
                        explosionObject.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent));
                    }
                    else
                    {
                        explosionObject.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent);
                    }
                    if (!AssetDatabase.Contains(explosionObject.materials[i]))
                    {
                        explosionObject.materials[i].name = explosionObject.materials[i].shader.name;
                    }
                    if (!AssetDatabase.IsMainAsset(explosionObject.materials[i]))
                    {
                        if (voxelBase.legacyAssetNaming)
                        {
                            explosionObject.materials[i].name = string.Format("explosion_mat{0}", i);
                        }
                        else
                        {
                            explosionObject.materials[i].name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_explosion_{0}", i);
                        }
                    }
                    if (!AssetDatabase.Contains(explosionObject.materials[i]))
                    {
                        voxelBaseCore.AddObjectToPrefabAsset(explosionObject.materials[i]);
                    }
                }
            }
            else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
            {
                explosionObject.materials = null;
                for (int chunkIndex = 0; chunkIndex < explosionObject.chunksExplosion.Length; chunkIndex++)
                {
                    var explosionChunk = explosionObject.chunksExplosion[chunkIndex];
                    if (explosionChunk.materials == null)
                    {
                        explosionChunk.materials = new List <Material>();
                    }
                    if (explosionChunk.materials.Count < voxelBase.materialData.Count)
                    {
                        for (int i = explosionChunk.materials.Count; i < voxelBase.materialData.Count; i++)
                        {
                            explosionChunk.materials.Add(null);
                        }
                    }
                    else if (explosionChunk.materials.Count > voxelBase.materialData.Count)
                    {
                        explosionChunk.materials.RemoveRange(voxelBase.materialData.Count, explosionChunk.materials.Count - voxelBase.materialData.Count);
                    }
                    for (int i = 0; i < voxelBase.materialData.Count; i++)
                    {
                        if (!voxelObject.chunks[chunkIndex].materialIndexes.Contains(i))
                        {
                            if (explosionChunk.materials[i] != null)
                            {
                                explosionChunk.materials[i] = null;
                                voxelBaseCore.DestroyUnusedObjectInPrefabObject();
                            }
                            continue;
                        }
                        if (explosionChunk.materials[i] == null)
                        {
                            explosionChunk.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent));
                        }
                        else
                        {
                            explosionChunk.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent);
                        }
                        if (!AssetDatabase.Contains(explosionChunk.materials[i]))
                        {
                            explosionChunk.materials[i].name = explosionChunk.materials[i].shader.name;
                        }
                        if (!AssetDatabase.IsMainAsset(explosionChunk.materials[i]))
                        {
                            if (voxelBase.legacyAssetNaming)
                            {
                                explosionChunk.materials[i].name = string.Format("{0}_explosion_mat{1}", explosionChunk.name, i);
                            }
                            else
                            {
                                explosionChunk.materials[i].name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, i);
                            }
                        }
                        if (!AssetDatabase.Contains(explosionChunk.materials[i]))
                        {
                            voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.materials[i]);
                        }
                    }
                }
            }
            else
            {
                Assert.IsTrue(false);
            }
            #endregion
        }