public void generateTexAndMesh(string parentFolder, string savePath, string dataFileName)
        {
            int numBones = animData.totalBoneNum;

            // 重新生成mesh
            rebuildAllMeshes(savePath, parentFolder);

            // 将骨骼矩阵写入纹理
            var tex2D = new Texture2D(animData.texWidth, animData.texHeight, TextureFormat.RGBA32, false);

            tex2D.filterMode = FilterMode.Point;
            int                 clipIdx  = 0;
            int                 pixelIdx = 0;
            Vector2Int          pixelUv;
            GpuSkinningAnimClip boneAnimation = null;
            AnimationClip       clip          = null;
            List <Matrix4x4>    boneMatrices  = null;

            for (clipIdx = 0; clipIdx < animClips.Length; ++clipIdx)
            {
                boneAnimation = animData.clips[clipIdx];
                clip          = animClips[clipIdx];
                for (int frameIndex = 0; frameIndex < boneAnimation.Length(); frameIndex++)
                {
                    boneMatrices = samplerAnimationClipBoneMatrices(curGameObject, clip, (float)frameIndex / clip.frameRate);
                    for (int boneIndex = 0; boneIndex < numBones; boneIndex++)
                    {
                        Matrix4x4  matrix   = boneMatrices[boneIndex];
                        Quaternion rotation = ToQuaternion(matrix);
                        Vector3    scale    = matrix.lossyScale;
                        float      sx       = Mathf.Floor(scale.x * 100.0f);
                        float      sy       = Mathf.Floor(scale.y * 100.0f);
                        float      sz       = Mathf.Floor(scale.z * 100.0f);
                        if ((sx - sy) > 5.0f ||
                            (sx - sz) > 5.0f ||
                            (sy - sz) > 5.0f)
                        {
                            Transform remapBone = null;
                            foreach (var key in boneIds.Keys)
                            {
                                if (boneIds[key] == boneIndex)
                                {
                                    remapBone = key;
                                    break;
                                }
                            }
                            string strLog = string.Format("AnimClip scale X Y Z not equal: {0} -> {1} {2}", curGameObject.name, boneAnimation.name, remapBone.transform.name);
                            Warning("AnimClip scale", strLog);
                        }

                        pixelUv = convertPixel2UV(pixelIdx++);

                        Color color1 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(rotation.x), convertFloat32toFloat16Bytes(rotation.y));
                        tex2D.SetPixel(pixelUv.x, pixelUv.y, color1);
                        pixelUv = convertPixel2UV(pixelIdx++);
                        Color color2 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(rotation.z), convertFloat32toFloat16Bytes(rotation.w));
                        tex2D.SetPixel(pixelUv.x, pixelUv.y, color2);
                        pixelUv = convertPixel2UV(pixelIdx++);
                        Color color3 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(matrix.GetColumn(3).x), convertFloat32toFloat16Bytes(matrix.GetColumn(3).y));
                        tex2D.SetPixel(pixelUv.x, pixelUv.y, color3);
                        pixelUv = convertPixel2UV(pixelIdx++);
                        Color color4 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(matrix.GetColumn(3).z), convertFloat32toFloat16Bytes(Mathf.Clamp01(matrix.lossyScale.magnitude)));
                        tex2D.SetPixel(pixelUv.x, pixelUv.y, color4);

                        //Debug.Log("==============frameIndex========start========"+ frameIndex);
                        //Debug.Log("=======rotation==========="+ rotation.x+", "+ rotation.y+", " + rotation.z +", "+rotation.w);
                        //Vector4 rrrr = convertColors2Halfs(color1, color2);
                        //Debug.Log("=======rotation===22======" + rrrr.x + ", " + rrrr.y + ", " + rrrr.z + ", " + rrrr.w);
                        //Debug.Log("=======translation===========" + matrix.GetColumn(3).x + ", " + matrix.GetColumn(3).y + ", " + matrix.GetColumn(3).z + ", " + Mathf.Clamp01(matrix.lossyScale.magnitude));
                        //Vector4 ttttt = convertColors2Halfs(color3, color4);
                        //Debug.Log("=======translation===22======" + ttttt.x + ", " + ttttt.y + ", " + ttttt.z + ", " + ttttt.w);
                        //Debug.Log("==============frameIndex========end========" + frameIndex);
                    }
                }
            }
            tex2D.Apply();
            // 导出动画纹理
            animTexturePath = savePath + dataFileName.Replace(".asset", "") + ".png";
            exportTexture(tex2D, animTexturePath);
            setAnimationTextureProperties(animTexturePath);

            // 存储
            string filePath = savePath + dataFileName;

            AssetDatabase.CreateAsset(animData, filePath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
        public void generateTexAndMesh_verticesAnim(string parentFolder, string savePath, string dataFileName)
        {
            // 重新生成mesh(这一步生成的mesh还是带骨骼indices和骨骼权重的,但顶点动画是不需要这些数据的,后面会删掉)
            rebuildAllMeshes(savePath, parentFolder);

            // 将骨骼矩阵写入纹理
            var tex2D = new Texture2D(animData.texWidth, animData.texHeight, TextureFormat.RGB24, false);

            tex2D.filterMode = FilterMode.Point;
            int clipIdx         = 0;
            int pixelIdx        = 0;
            int totalFrameIndex = 0;
            GpuSkinningAnimClip boneAnimation = null;
            AnimationClip       clip = null;
            List <Matrix4x4>    boneMatrices = null;
            Vector4             boneIndices, boneWeights;
            Matrix4x4           boneMatrix0, boneMatrix1, boneMatrix2, boneMatrix3;
            Vector3             src_vertex;
            Vector4             vertex, position;

            for (clipIdx = 0; clipIdx < animClips.Length; ++clipIdx)
            {
                boneAnimation = animData.clips[clipIdx];
                clip          = animClips[clipIdx];
                for (int frameIndex = 0; frameIndex < boneAnimation.Length(); frameIndex++)
                {
                    boneMatrices = samplerAnimationClipBoneMatrices(curGameObject, clip, (float)frameIndex / (clip.frameRate / compression));
                    for (int vertexIndex = 0; vertexIndex < instMesh.vertices.Length; ++vertexIndex)
                    {
                        src_vertex  = instMesh.vertices[vertexIndex];
                        vertex      = new Vector4(src_vertex.x, src_vertex.y, src_vertex.z, 1);
                        boneIndices = boneIndicesList[vertexIndex];
                        boneWeights = boneWeightsList[vertexIndex];
                        boneMatrix0 = boneMatrices[Mathf.RoundToInt(boneIndices.x)];
                        boneMatrix1 = boneMatrices[Mathf.RoundToInt(boneIndices.y)];
                        boneMatrix2 = boneMatrices[Mathf.RoundToInt(boneIndices.z)];
                        boneMatrix3 = boneMatrices[Mathf.RoundToInt(boneIndices.w)];
                        matrixMulFloat(ref boneMatrix0, boneWeights.x);
                        matrixMulFloat(ref boneMatrix1, boneWeights.y);
                        matrixMulFloat(ref boneMatrix2, boneWeights.z);
                        matrixMulFloat(ref boneMatrix3, boneWeights.w);
                        position = (matrixAddMatrix(matrixAddMatrix(boneMatrix0, boneMatrix1), matrixAddMatrix(boneMatrix2, boneMatrix3))) * vertex;
                        Color[] colors = convertThreeFloat16Bytes2TwoColor(convertFloat32toFloat16Bytes(position.x), convertFloat32toFloat16Bytes(position.y), convertFloat32toFloat16Bytes(position.z));
                        tex2D.SetPixel(vertexIndex, totalFrameIndex * 2, colors[0]);
                        tex2D.SetPixel(vertexIndex, totalFrameIndex * 2 + 1, colors[1]);
                    }

                    ++totalFrameIndex;
                }
            }
            tex2D.Apply();
            // 导出动画纹理
            animTexturePath = savePath + dataFileName.Replace(".asset", "") + ".png";
            exportTexture(tex2D, animTexturePath);
            setAnimationTextureProperties(animTexturePath);

            // 存储数据
            string filePath = savePath + dataFileName;

            AssetDatabase.CreateAsset(animData, filePath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            // 删除mesh的骨骼信息
            instMesh.uv2 = null;
            instMesh.uv3 = null;
            // 添加mesh的顶点索引 (TODO: unity shader中是否可以直接获取?)
            List <Vector4> indices = new List <Vector4>();

            for (int vertexIndex = 0; vertexIndex < instMesh.vertices.Length; ++vertexIndex)
            {
                indices.Add(new Vector4(vertexIndex, vertexIndex, vertexIndex, vertexIndex));
            }
            instMesh.SetUVs(1, indices);

            EditorUtility.SetDirty(instMesh);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();

            AssetDatabase.Refresh();
        }