void GenerateMeshFromBoneConstraints(SPCRJointDynamicsController Controller)
    {
        var vertices    = new List <Vector3>();
        var boneWeights = new List <BoneWeight>();
        var bindposes   = new List <Matrix4x4>();

        var AllBones        = new List <Transform>();
        var HorizontalBones = new List <List <Transform> >();

        for (int i = 0; i <= Controller._RootPointTbl.Length; ++i)
        {
            var verticalBones = new List <Transform>();
            var child         = Controller._RootPointTbl[i % Controller._RootPointTbl.Length];
            while (child != null)
            {
                vertices.Add(child.transform.position);
                boneWeights.Add(new BoneWeight()
                {
                    boneIndex0 = AllBones.Count,
                    weight0    = 1.0f,
                });
                bindposes.Add(child.transform.worldToLocalMatrix);
                AllBones.Add(child.transform);
                verticalBones.Add(child.transform);
                child = Controller.GetChildJointDynamicsPoint(child);
            }
            HorizontalBones.Add(verticalBones);
        }

        var uvs = new List <Vector2>();

        for (int h = 0; h < HorizontalBones.Count; ++h)
        {
            for (int v = 0; v < HorizontalBones[h].Count; ++v)
            {
                uvs.Add(new Vector2(
                            (float)h / (float)(HorizontalBones.Count - 1),
                            (float)v / (float)(HorizontalBones[h].Count - 1)));
            }
        }

        int index           = 0;
        var triangles       = new List <int>();
        var HorizontalCount = HorizontalBones.Count;

        for (int h = 0; h < HorizontalCount - 1; ++h)
        {
            var Vertical0Count = HorizontalBones[h].Count;
            var Vertical1Count = HorizontalBones[h + 1].Count;
            if (Vertical0Count == Vertical1Count)
            {
                for (int v = 0; v < Vertical0Count - 1; ++v)
                {
                    var top0 = index;
                    var top1 = index + Vertical0Count;
                    var x0y0 = top0 + v;
                    var x1y0 = top0 + v + 1;
                    var x0y1 = top1 + v;
                    var x1y1 = top1 + v + 1;
                    triangles.Add(x0y0);
                    triangles.Add(x1y0);
                    triangles.Add(x1y1);
                    triangles.Add(x1y1);
                    triangles.Add(x0y1);
                    triangles.Add(x0y0);
                }
            }
            index += Vertical0Count;
        }

        var mesh = new Mesh();

        mesh.indexFormat = vertices.Count > 65535 ? IndexFormat.UInt32 : IndexFormat.UInt16;
        mesh.vertices    = vertices.ToArray();
        mesh.uv          = uvs.ToArray();
        mesh.boneWeights = boneWeights.ToArray();
        mesh.bindposes   = bindposes.ToArray();
        mesh.triangles   = triangles.ToArray();
        RecalculateNormals(mesh);

        var renderers = Controller.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>();

        if (renderers.Length != 0)
        {
            var Path    = AssetDatabase.GetAssetPath(renderers[renderers.Length - 1].sharedMesh);
            var DirName = System.IO.Path.GetDirectoryName(Path);
            AssetDatabase.CreateAsset(mesh, DirName + "/" + Controller.gameObject.name + "_" + Controller.Name + ".asset");
            AssetDatabase.Refresh();
        }

        var skinMesh = Controller.gameObject.GetComponent <SkinnedMeshRenderer>();

        if (skinMesh == null)
        {
            skinMesh = Controller.gameObject.AddComponent <SkinnedMeshRenderer>();
        }
        skinMesh.bones      = AllBones.ToArray();
        skinMesh.sharedMesh = mesh;
        skinMesh.rootBone   = Controller._RootTransform;
        var meshFilter = Controller.gameObject.GetComponent <MeshFilter>();

        if (meshFilter == null)
        {
            meshFilter = Controller.gameObject.AddComponent <MeshFilter>();
        }
        meshFilter.mesh = mesh;
    }
    void CreationSubdivisionJoint(SPCRJointDynamicsController Controller, int HDivCount, int VDivCount)
    {
        var VCurve = new List <CurveData>();
        var HCurve = new List <CurveData>();

        var RootTbl = Controller._RootPointTbl;

#if UNITY_2018_3_OR_NEWER
        PrefabUtility.UnpackPrefabInstance(Controller.gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
#else//UNITY_2018_3_OR_NEWER
        PrefabUtility.DisconnectPrefabInstance(Controller.gameObject);
#endif//UNITY_2018_3_OR_NEWER

        for (int i = 0; i < RootTbl.Length; ++i)
        {
            float Length = 0.0f;
            var   Curve  = new CurveData();
            var   Point  = RootTbl[i];
            while (Point != null)
            {
                Curve.Keys.Add(new CurveKey()
                {
                    Length = Length,
                    Value  = Point.transform.position,
                });
                var NextPoint = Controller.GetChildJointDynamicsPoint(Point);
                if (NextPoint != null)
                {
                    Length += (NextPoint.transform.position - Point.transform.position).magnitude;
                }
                Point = NextPoint;
            }
            Curve.CreateSpileData(Length, false);
            VCurve.Add(Curve);
        }

        for (int v = 0; v <= VDivCount; ++v)
        {
            float Rate     = (float)v / (float)VDivCount;
            var   Curve    = new CurveData();
            var   OldPoint = VCurve[0].ComputeLinear(Rate);
            float Length   = 0.0f;
            for (int i = 0; i < VCurve.Count; ++i)
            {
                var NewPoint = VCurve[i].ComputeLinear(Rate);
                Length += (NewPoint - OldPoint).magnitude;
                Curve.Keys.Add(new CurveKey()
                {
                    Length = Length,
                    Value  = NewPoint,
                });
                OldPoint = NewPoint;
            }
            Curve.CreateSpileData(Length, true);
            HCurve.Add(Curve);
        }

        var RootPointList = new List <SPCRJointDynamicsPoint>();
        for (int h = 0; h < HDivCount; ++h)
        {
            float Rate   = (float)h / (float)HDivCount;
            var   parent = Controller._RootTransform;
            for (int i = 0; i < HCurve.Count; ++i)
            {
                var Position = HCurve[i].ComputeSpline(Rate);
                var go       = new GameObject(h.ToString("D3") + "_" + i.ToString("D3"));
                var pt       = go.AddComponent <SPCRJointDynamicsPoint>();
                go.transform.SetParent(parent);
                go.transform.position = Position;
                if (i == 0)
                {
                    RootPointList.Add(pt);
                }
                parent = go.transform;
            }
        }

        for (int i = 0; i < RootTbl.Length; ++i)
        {
            SetTransformScaleZero(RootTbl[i].transform);
        }

        Controller._RootPointTbl = RootPointList.ToArray();
        Controller.UpdateJointConnection();

        GenerateMeshFromBoneConstraints(Controller);
    }