Example #1
0
        public VoxData GetLODVoxelData(int lodLevel)
        {
            if (SizeX <= 1 || SizeY <= 1 || SizeZ <= 1)
            {
                return(null);
            }
            lodLevel = Mathf.Clamp(lodLevel, 0, 8);
            if (lodLevel <= 1)
            {
                return(this);
            }
            if (SizeX <= lodLevel && SizeY <= lodLevel && SizeZ <= lodLevel)
            {
                return(null);
            }
            VoxData data = new VoxData();

            data.SizeX   = Mathf.Max(Mathf.CeilToInt((float)SizeX / lodLevel), 1);
            data.SizeY   = Mathf.Max(Mathf.CeilToInt((float)SizeY / lodLevel));
            data.SizeZ   = Mathf.Max(Mathf.CeilToInt((float)SizeZ / lodLevel));
            data.Version = Version;
            data.Palatte = Palatte;
            data.Voxels  = new int[data.SizeX, data.SizeY, data.SizeZ];
            for (int x = 0; x < data.SizeX; x++)
            {
                for (int y = 0; y < data.SizeY; y++)
                {
                    for (int z = 0; z < data.SizeZ; z++)
                    {
                        data.Voxels[x, y, z] = this.GetMajorityColorIndex(x * lodLevel, y * lodLevel, z * lodLevel, lodLevel);
                    }
                }
            }
            return(data);
        }
Example #2
0
        static int ReadVoxelChunk(BinaryReader _br, VoxData _mainData, List <Vector3> tempSize, ref List <int[, , ]> tempVoxels)
        {
            int chunkSize    = _br.ReadInt32();
            int childrenSize = _br.ReadInt32();
            int numVoxels    = _br.ReadInt32();

            int[,,] temp = new int[
                (int)tempSize[tempVoxels.Count].x,
                (int)tempSize[tempVoxels.Count].y,
                (int)tempSize[tempVoxels.Count].z
                           ];

            for (int i = 0; i < numVoxels; ++i)
            {
                int x = (int)_br.ReadByte();
                int y = (int)_br.ReadByte();
                int z = (int)_br.ReadByte();
                temp[x, y, z] = _br.ReadByte();
            }

            tempVoxels.Add(temp);

            if (childrenSize > 0)
            {
                _br.ReadBytes(childrenSize);
            }

            return(chunkSize + childrenSize + 4 * 3);
        }
Example #3
0
        public static byte[] GetMainByte(VoxData _voxData)
        {
            List <byte> _byte = new List <byte>();

            ///*

            // "VOX "
            _byte.AddRange(Encoding.Default.GetBytes("VOX "));

            // "VERSION "
            _byte.AddRange(_voxData.Version);

            // ID --> MAIN
            _byte.AddRange(Encoding.Default.GetBytes("MAIN"));

            // Main Chunk Size
            _byte.AddRange(BitConverter.GetBytes(0));

            // Main Chunk Children Size
            byte[] _vox = GetVoxByte(_voxData, _voxData.Palatte);
            _byte.AddRange(BitConverter.GetBytes(_vox.Length));

            // Vox Chunk
            _byte.AddRange(_vox);

            //*/

            byte[] _ans = new byte[_byte.Count];
            _byte.CopyTo(_ans);
            return(_ans);
        }
Example #4
0
        public void CreateObj(VoxData voxData, int frame)
        {
            InitVoxels(voxData, frame);

            FixVisible();

            CreateVoxelObj();
        }
Example #5
0
        public VoxData GetLODVoxelData(int lodLevel)
        {
            VoxData data = new VoxData()
            {
                SizeX   = new int[Voxels.Length],
                SizeY   = new int[Voxels.Length],
                SizeZ   = new int[Voxels.Length],
                Version = Version,
                Palatte = Palatte,
                Voxels  = new int[Voxels.Length][, , ],
            };

            for (int index = 0; index < Voxels.Length; index++)
            {
                if (SizeX[index] <= 1 || SizeY[index] <= 1 || SizeZ[index] <= 1)
                {
                    data.Voxels[index] = null;
                    continue;
                }

                lodLevel = Mathf.Clamp(lodLevel, 0, 8);
                if (lodLevel <= 1)
                {
                    data.SizeX[index]  = SizeX[index];
                    data.SizeY[index]  = SizeY[index];
                    data.SizeZ[index]  = SizeZ[index];
                    data.Voxels[index] = Voxels[index];
                    continue;
                }

                if (SizeX[index] <= lodLevel && SizeY[index] <= lodLevel && SizeZ[index] <= lodLevel)
                {
                    data.Voxels[index] = null;
                    continue;
                }

                data.SizeX[index]  = Mathf.Max(Mathf.CeilToInt((float)SizeX[index] / lodLevel), 1);
                data.SizeY[index]  = Mathf.Max(Mathf.CeilToInt((float)SizeY[index] / lodLevel));
                data.SizeZ[index]  = Mathf.Max(Mathf.CeilToInt((float)SizeZ[index] / lodLevel));
                data.Voxels[index] = new int[data.SizeX[index], data.SizeY[index], data.SizeZ[index]];
                for (int x = 0; x < data.SizeX[index]; x++)
                {
                    for (int y = 0; y < data.SizeY[index]; y++)
                    {
                        for (int z = 0; z < data.SizeZ[index]; z++)
                        {
                            data.Voxels[index][x, y, z] = GetMajorityColorIndex(index, x * lodLevel, y * lodLevel, z * lodLevel, lodLevel);
                        }
                    }
                }
            }
            return(data);
        }
Example #6
0
        public VoxData GetVoxData()
        {
            VoxData vox = new VoxData();

            Vector3 sizeAll = SizeAll;

            vox.SizeX = new int[1] {
                (int)sizeAll.x
            };
            vox.SizeY = new int[1] {
                (int)sizeAll.y
            };
            vox.SizeZ = new int[1] {
                (int)sizeAll.z
            };

            vox.Voxels    = new int[1][, , ];
            vox.Voxels[0] = new int[vox.SizeX[0], vox.SizeY[0], vox.SizeZ[0]];
            List <Color> pl = new List <Color> {
                new Color()
            };

            for (int i = 0; i < MatrixList.Count; i++)
            {
                for (int x = 0; x < MatrixList[i].SizeX; x++)
                {
                    for (int y = 0; y < MatrixList[i].SizeY; y++)
                    {
                        for (int z = 0; z < MatrixList[i].SizeZ; z++)
                        {
                            int v = MatrixList[i][x, y, z];
                            if (v != 0)
                            {
                                Color color = ColorFormat == 0 ? RGB(v) : BGR(v);
                                int   index = pl.IndexOf(color);
                                if (index == -1)
                                {
                                    pl.Add(color);
                                    index = pl.Count - 1;
                                }
                                vox.Voxels[0][x + MatrixList[i].PosX, y + MatrixList[i].PosY, z + MatrixList[i].PosZ] = index + 1;
                            }
                        }
                    }
                }
            }

            vox.Palatte = pl.ToArray();

            return(vox);
        }
Example #7
0
        public void CreateVoxelMesh(VoxData voxelData, float scale, Vector3 pivot, ref Mesh[] meshs, ref Texture2D texture)
        {
            // Init Voxels
            InitVoxels(voxelData, scale, pivot);

            // Visibility
            FixVisible();

            // Faces
            Getfaces();

            // Mesh
            CreateMesh(voxelData, ref meshs, ref texture);
        }
Example #8
0
        static int ReadSizeChunk(BinaryReader _br, VoxData _mainData)
        {
            int chunkSize    = _br.ReadInt32();
            int childrenSize = _br.ReadInt32();

            _mainData.SizeX = _br.ReadInt32();
            _mainData.SizeY = _br.ReadInt32();
            _mainData.SizeZ = _br.ReadInt32();
            ///*
            _mainData.Voxels = new int[_mainData.SizeX, _mainData.SizeY, _mainData.SizeZ];
            //*/
            if (childrenSize > 0)
            {
                _br.ReadBytes(childrenSize);
            }

            return(chunkSize + childrenSize + 4 * 3);
        }
Example #9
0
        public void CreateVoxelMesh(VoxData voxelData, float scale, Vector3 pivot, ref Texture2D texture, ref string objFile)
        {
            // Init Voxels
            InitVoxels(voxelData, scale, pivot);

            // Visibility
            FixVisible();

            // Faces
            Getfaces();

            // Mesh
            Mesh[] meshs = null;
            CreateMesh(voxelData, ref meshs, ref texture);

            // Obj
            objFile = CreateObj(meshs, objFile);
        }
Example #10
0
        /// <summary>
        /// 初始化 voxel 信息数据
        /// </summary>
        /// <param name="voxData"></param>
        /// <param name="frame"></param>
        private void InitVoxels(VoxData voxData, int frame)
        {
            this._voxData = voxData;

            SizeX = voxData.SizeX[frame];
            SizeY = voxData.SizeY[frame];
            SizeZ = voxData.SizeZ[frame];

            Voxels = new Voxel[SizeX, SizeY, SizeZ];
            for (int i = 0; i < SizeX; i++)
            {
                for (int j = 0; j < SizeY; j++)
                {
                    for (int k = 0; k < SizeZ; k++)
                    {
                        Voxels[i, j, k].Init();
                        Voxels[i, j, k].ColorIndex = voxData.Voxels[frame][i, j, k];
                    }
                }
            }
        }
Example #11
0
 private void InitVoxels(VoxData voxelData, float scale, Vector3 pivot)
 {
     Scale         = scale;
     Pivot         = pivot;
     SizeX         = voxelData.SizeX;
     SizeY         = voxelData.SizeY;
     SizeZ         = voxelData.SizeZ;
     MainVoxelData = voxelData;
     Voxels        = new Voxel[SizeX, SizeY, SizeZ];
     for (int i = 0; i < SizeX; i++)
     {
         for (int j = 0; j < SizeY; j++)
         {
             for (int k = 0; k < SizeZ; k++)
             {
                 Voxels[i, j, k].Init();
                 Voxels[i, j, k].ColorIndex = MainVoxelData.Voxels[i, j, k];
             }
         }
     }
 }
Example #12
0
        static int ReadVoxelChunk(BinaryReader _br, VoxData _mainData)
        {
            int chunkSize    = _br.ReadInt32();
            int childrenSize = _br.ReadInt32();
            int numVoxels    = _br.ReadInt32();

            for (int i = 0; i < numVoxels; ++i)
            {
                int x = (int)_br.ReadByte();
                int y = (int)_br.ReadByte();
                int z = (int)_br.ReadByte();

                _mainData.Voxels[x, y, z] = _br.ReadByte();
            }

            if (childrenSize > 0)
            {
                _br.ReadBytes(childrenSize);
            }

            return(chunkSize + childrenSize + 4 * 3);
        }
Example #13
0
        public static byte[] GetVoxByte(VoxData _data, Color[] _palatte)
        {
            List <byte> _byte = new List <byte>();

            ///*

            // content
            for (int index = 0; index < _data.Voxels.Length; index++)
            {
                // --- SIZE ---
                //size / children size
                _byte.AddRange(Encoding.Default.GetBytes("SIZE"));
                _byte.AddRange(BitConverter.GetBytes(12));
                _byte.AddRange(BitConverter.GetBytes(0));

                _byte.AddRange(BitConverter.GetBytes(_data.SizeX[index]));
                _byte.AddRange(BitConverter.GetBytes(_data.SizeY[index]));
                _byte.AddRange(BitConverter.GetBytes(_data.SizeZ[index]));

                // --- XYZI ---
                //size / children size
                _byte.AddRange(Encoding.Default.GetBytes("XYZI"));
                _byte.AddRange(BitConverter.GetBytes(_data.VoxelNum(index) * 4 + 4));
                _byte.AddRange(BitConverter.GetBytes(0));
                _byte.AddRange(BitConverter.GetBytes(_data.VoxelNum(index)));

                for (int i = 0; i < _data.SizeX[index]; i++)
                {
                    for (int j = 0; j < _data.SizeY[index]; j++)
                    {
                        for (int k = 0; k < _data.SizeZ[index]; k++)
                        {
                            if (_data.Voxels[index][i, j, k] != 0)
                            {
                                _byte.Add((byte)i);
                                _byte.Add((byte)j);
                                _byte.Add((byte)k);
                                _byte.Add((byte)_data.Voxels[index][i, j, k]);
                            }
                        }
                    }
                }
            }


            // --- RGBA ---
            //size / children size
            _byte.AddRange(Encoding.Default.GetBytes("RGBA"));
            _byte.AddRange(BitConverter.GetBytes(1024));
            _byte.AddRange(BitConverter.GetBytes(0));

            for (int i = 0; i < 256; i++)
            {
                Color _color = i < _palatte.Length ? _palatte[i] : new Color();
                _byte.Add((byte)(_color.r * 255.0f));
                _byte.Add((byte)(_color.g * 255.0f));
                _byte.Add((byte)(_color.b * 255.0f));
                _byte.Add((byte)(_color.a * 255.0f));
            }

            //*/

            // --- Final ---
            byte[] _ans = new byte[_byte.Count];
            _byte.CopyTo(_ans);
            return(_ans);
        }
Example #14
0
        public static VoxData LoadVoxel(byte[] _data)
        {
            if (_data[0] != 'V' || _data[1] != 'O' || _data[2] != 'X' || _data[3] != ' ')
            {
                Debug.LogError("Error Magic Number");
                return(null);
            }

            using (MemoryStream _ms = new MemoryStream(_data)) {
                using (BinaryReader _br = new BinaryReader(_ms)) {
                    VoxData          _mainData  = new VoxData();
                    List <int[, , ]> tempVoxels = new List <int[, , ]>();
                    List <Vector3>   tempSizes  = new List <Vector3>();
                    ///*

                    // VOX_
                    _br.ReadInt32();

                    // VERSION
                    _mainData.Version = _br.ReadBytes(4);

                    byte[] _chunkId = _br.ReadBytes(4);
                    if (_chunkId[0] != 'M' || _chunkId[1] != 'A' || _chunkId[2] != 'I' || _chunkId[3] != 'N')
                    {
                        Debug.LogError("Error main ID");
                        return(null);
                    }

                    int _chunkSize    = _br.ReadInt32();
                    int _childrenSize = _br.ReadInt32();

                    _br.ReadBytes(_chunkSize);

                    int _readSize = 0;
                    while (_readSize < _childrenSize)
                    {
                        _chunkId = _br.ReadBytes(4);
                        if (_chunkId[0] == 'S' && _chunkId[1] == 'I' && _chunkId[2] == 'Z' && _chunkId[3] == 'E')
                        {
                            _readSize += ReadSizeChunk(_br, ref tempSizes);
                        }
                        else if (_chunkId[0] == 'X' && _chunkId[1] == 'Y' && _chunkId[2] == 'Z' && _chunkId[3] == 'I')
                        {
                            _readSize += ReadVoxelChunk(_br, _mainData, tempSizes, ref tempVoxels);
                        }
                        else if (_chunkId[0] == 'R' && _chunkId[1] == 'G' && _chunkId[2] == 'B' && _chunkId[3] == 'A')
                        {
                            _mainData.Palatte = new Color[256];
                            _readSize        += ReadPalattee(_br, _mainData.Palatte);
                        }
                        else
                        {
                            int chunkSize    = _br.ReadInt32();
                            int childrenSize = _br.ReadInt32();
                            _br.ReadBytes(chunkSize + childrenSize);
                            _readSize += chunkSize + childrenSize + 4 + 4 + 4;
                        }
                    }

                    // Add Voxels
                    _mainData.Voxels = tempVoxels.ToArray();

                    // Add Sizes
                    _mainData.SizeX = new int[tempSizes.Count];
                    _mainData.SizeY = new int[tempSizes.Count];
                    _mainData.SizeZ = new int[tempSizes.Count];
                    for (int i = 0; i < tempSizes.Count; i++)
                    {
                        _mainData.SizeX[i] = (int)tempSizes[i].x;
                        _mainData.SizeY[i] = (int)tempSizes[i].y;
                        _mainData.SizeZ[i] = (int)tempSizes[i].z;
                    }

                    if (_mainData.Palatte == null)
                    {
                        _mainData.Palatte = DefaultPallete;
                    }

                    return(_mainData);
                }
            }
        }
Example #15
0
        public static VoxData LoadVoxel(byte[] _data)
        {
            if (_data[0] != 'V' || _data[1] != 'O' || _data[2] != 'X' || _data[3] != ' ')
            {
                Debug.LogError("Error Magic Number");
                return(null);
            }

            using (MemoryStream _ms = new MemoryStream(_data)) {
                using (BinaryReader _br = new BinaryReader(_ms)) {
                    VoxData _mainData = new VoxData();

                    ///*

                    // VOX_
                    _br.ReadInt32();

                    // VERSION
                    _mainData.Version = _br.ReadBytes(4);

                    byte[] _chunkId = _br.ReadBytes(4);
                    if (_chunkId[0] != 'M' || _chunkId[1] != 'A' || _chunkId[2] != 'I' || _chunkId[3] != 'N')
                    {
                        Debug.LogError("Error main ID");
                        return(null);
                    }

                    int _chunkSize    = _br.ReadInt32();
                    int _childrenSize = _br.ReadInt32();

                    _br.ReadBytes(_chunkSize);

                    int _readSize = 0;
                    while (_readSize < _childrenSize)
                    {
                        _chunkId = _br.ReadBytes(4);
                        if (_chunkId[0] == 'S' && _chunkId[1] == 'I' && _chunkId[2] == 'Z' && _chunkId[3] == 'E')
                        {
                            _readSize += ReadSizeChunk(_br, _mainData);
                        }
                        else if (_chunkId[0] == 'X' && _chunkId[1] == 'Y' && _chunkId[2] == 'Z' && _chunkId[3] == 'I')
                        {
                            _readSize += ReadVoxelChunk(_br, _mainData);
                        }
                        else if (_chunkId[0] == 'R' && _chunkId[1] == 'G' && _chunkId[2] == 'B' && _chunkId[3] == 'A')
                        {
                            _mainData.Palatte = new Color[256];
                            _readSize        += ReadPalattee(_br, _mainData.Palatte);
                        }
                        else
                        {
                            int chunkSize    = _br.ReadInt32();
                            int childrenSize = _br.ReadInt32();
                            _br.ReadBytes(chunkSize + childrenSize);
                            _readSize += chunkSize + childrenSize + 4 + 4 + 4;
                        }
                    }

                    if (_mainData.Palatte == null)
                    {
                        _mainData.Palatte = DefaultPallete;
                    }



                    return(_mainData);
                }
            }
        }
Example #16
0
        private void CreateMesh(VoxData voxelData, ref Mesh[] meshs, ref Texture2D aimTexture)
        {
            int num = VoxelFaces.Count / MaxFacesInOneMesh + 1;

            if (VoxelFaces.Count % MaxFacesInOneMesh == 0)
            {
                num--;
            }

            meshs = new Mesh[num];
            List <Dictionary <int, int> > uvIdMaps    = new List <Dictionary <int, int> >();
            List <Texture2D[]>            temptxtList = new List <Texture2D[]>();

            for (int index = 0; index < num; index++)
            {
                List <VoxelFace> Faces = new List <VoxelFace>(VoxelFaces.GetRange(index * MaxFacesInOneMesh, Mathf.Min(MaxFacesInOneMesh, VoxelFaces.Count - index * MaxFacesInOneMesh)));


                #region --- Vertices ---

                List <Vector3> voxelVertices = new List <Vector3>();

                for (int i = 0; i < Faces.Count; i++)
                {
                    Vector3[] points = Faces[i].Points;
                    for (int j = 0; j < 4; j++)
                    {
                        points[j] -= new Vector3(SizeX * Pivot.x, SizeZ * Pivot.y, SizeY * Pivot.z);
                        points[j] *= Scale;
                    }
                    voxelVertices.AddRange(points);
                }

                #endregion


                #region --- Triangles ---

                List <int> voxelTriangles = new List <int>();

                for (int i = 0; i < Faces.Count; i++)
                {
                    if (Faces[i].direction == Direction.Front || Faces[i].direction == Direction.Up || Faces[i].direction == Direction.Right)
                    {
                        voxelTriangles.AddRange(new int[6] {
                            i * 4 + 2,
                            i * 4 + 1,
                            i * 4 + 0,
                            i * 4 + 3,
                            i * 4 + 1,
                            i * 4 + 2
                        });
                    }
                    else
                    {
                        voxelTriangles.AddRange(new int[6] {
                            i * 4 + 2,
                            i * 4 + 0,
                            i * 4 + 1,
                            i * 4 + 3,
                            i * 4 + 2,
                            i * 4 + 1
                        });
                    }
                }

                #endregion


                meshs[index] = new Mesh();
                meshs[index].Clear();
                meshs[index].SetVertices(voxelVertices);
                meshs[index].SetTriangles(voxelTriangles, 0);


                #region --- Texture ---


                List <Texture2D>      tempTextureList = new List <Texture2D>();
                List <int>            tempColorIndexs = new List <int>();
                Dictionary <int, int> UVidMap         = new Dictionary <int, int>();


                for (int i = 0; i < Faces.Count; i++)
                {
                    int width  = Faces[i].Width + 2;
                    int height = Faces[i].Height + 2;

                    Color[] _colors = new Color[width * height];

                    bool sameIndex    = true;
                    int  currentIndex = -1;

                    for (int u = 0; u < Faces[i].Width; u++)
                    {
                        for (int v = 0; v < Faces[i].Height; v++)
                        {
                            int colorIndex = 0;
                            switch (Faces[i].direction)
                            {
                            case Direction.Front:
                            case Direction.Back:
                                colorIndex = Voxels[u + Faces[i].VoxelX, Faces[i].VoxelY, v + Faces[i].VoxelZ].ColorIndex - 1;
                                break;

                            case Direction.Left:
                            case Direction.Right:
                                colorIndex = Voxels[Faces[i].VoxelX, u + Faces[i].VoxelY, v + Faces[i].VoxelZ].ColorIndex - 1;
                                break;

                            case Direction.Up:
                            case Direction.Down:
                                colorIndex = Voxels[u + Faces[i].VoxelX, v + Faces[i].VoxelY, Faces[i].VoxelZ].ColorIndex - 1;
                                break;
                            }
                            Color _c = MainVoxelData.Palatte[colorIndex];
                            _colors[(v + 1) * width + u + 1] = _c;


                            if (currentIndex == -1)
                            {
                                currentIndex = colorIndex;
                            }
                            if (sameIndex && currentIndex != colorIndex)
                            {
                                sameIndex = false;
                            }


                            #region --- Side ---

                            if (u == 0)
                            {
                                _colors[(v + 1) * width + u] = _c;
                            }

                            if (u == Faces[i].Width - 1)
                            {
                                _colors[(v + 1) * width + u + 2] = _c;
                            }

                            if (v == 0)
                            {
                                _colors[v * width + u + 1] = _c;
                            }

                            if (v == Faces[i].Height - 1)
                            {
                                _colors[(v + 2) * width + u + 1] = _c;
                            }

                            if (u == 0 && v == 0)
                            {
                                _colors[0] = _c;
                            }

                            if (u == 0 && v == Faces[i].Height - 1)
                            {
                                _colors[(v + 2) * width + u] = _c;
                            }

                            if (u == Faces[i].Width - 1 && v == 0)
                            {
                                _colors[v * width + u + 2] = _c;
                            }

                            if (u == Faces[i].Width - 1 && v == Faces[i].Height - 1)
                            {
                                _colors[(v + 2) * width + u + 2] = _c;
                            }

                            #endregion
                        }
                    }

                    Texture2D _texture = null;
                    int       oldID    = i;
                    if (sameIndex && currentIndex > 0)
                    {
                        if (tempColorIndexs.Contains(currentIndex))
                        {
                            oldID = tempColorIndexs.IndexOf(currentIndex);
                        }
                        else
                        {
                            Color c = MainVoxelData.Palatte[currentIndex];
                            _texture = new Texture2D(3, 3, TextureFormat.ARGB32, false, false);
                            _texture.SetPixels(new Color[9] {
                                c, c, c, c, c, c, c, c, c
                            });
                            tempTextureList.Add(_texture);
                            tempColorIndexs.Add(currentIndex);
                            oldID = tempTextureList.Count - 1;
                        }
                    }
                    else
                    {
                        _texture = new Texture2D(width, height, TextureFormat.ARGB32, false, false);
                        _texture.SetPixels(_colors);
                        tempTextureList.Add(_texture);
                        tempColorIndexs.Add(-1);
                        oldID = tempTextureList.Count - 1;
                    }
                    if (_texture)
                    {
                        _texture.wrapMode   = TextureWrapMode.Clamp;
                        _texture.filterMode = FilterMode.Point;
                        _texture.mipMapBias = 0f;
                        _texture.Apply();
                    }
                    UVidMap.Add(i, oldID);
                }

                temptxtList.Add(tempTextureList.ToArray());
                tempTextureList.Clear();
                uvIdMaps.Add(UVidMap);

                #endregion
            }

            // Combine Textures && Reset UV

            aimTexture = new Texture2D(1, 1);
            List <Texture2D> txtList = new List <Texture2D>();
            for (int i = 0; i < temptxtList.Count; i++)
            {
                txtList.AddRange(temptxtList[i]);
            }


            Rect[] tempUVs = aimTexture.PackTextures(txtList.ToArray(), 0);

            CutTexture(ref aimTexture, ref tempUVs);

            List <Rect> aimUVs = new List <Rect>(tempUVs);

            aimTexture.wrapMode   = TextureWrapMode.Clamp;
            aimTexture.filterMode = FilterMode.Point;
            aimTexture.mipMapBias = 0f;
            aimTexture.Apply();


            #region --- UV ---

            int rectIndexOffset = 0;
            for (int index = 0; index < num; index++)
            {
                List <VoxelFace> Faces = new List <VoxelFace>(VoxelFaces.GetRange(
                                                                  index * MaxFacesInOneMesh,
                                                                  Mathf.Min(MaxFacesInOneMesh, VoxelFaces.Count - index * MaxFacesInOneMesh)
                                                                  ));

                Rect[] rects = aimUVs.GetRange(
                    rectIndexOffset,
                    temptxtList[index].Length
                    ).ToArray();

                float gapX = 1f / aimTexture.width;
                float gapY = 1f / aimTexture.height;

                Vector2[] voxelUV = new Vector2[Faces.Count * 4];

                for (int i = 0; i < Faces.Count; i++)
                {
                    int rectID = uvIdMaps[index][i];
                    if (rectID >= rects.Length)
                    {
                        continue;
                    }
                    voxelUV[i * 4 + 0] = new Vector2(rects[rectID].xMin + gapX, rects[rectID].yMin + gapY);
                    voxelUV[i * 4 + 1] = new Vector2(rects[rectID].xMax - gapX, rects[rectID].yMin + gapY);
                    voxelUV[i * 4 + 2] = new Vector2(rects[rectID].xMin + gapX, rects[rectID].yMax - gapY);
                    voxelUV[i * 4 + 3] = new Vector2(rects[rectID].xMax - gapX, rects[rectID].yMax - gapY);
                }
                uvIdMaps[index].Clear();

                rectIndexOffset += temptxtList[index].Length;

                meshs[index].uv = voxelUV;
                meshs[index].RecalculateNormals();
            }

            uvIdMaps.Clear();
            aimUVs.Clear();

            #endregion
        }