static public void TransformKeyDataToWorld(this MotionDataInNative motionData)
        {
            var rotationKeyLength = motionData.StreamPool
                                    .Buffer(3)
                                    .Select(x => x[(int)KeyStreamSection.rotations].Stream.Length)
                                    .Sum()
            ;
            var dst = new NativeArray <KeyUnitInNative>(rotationKeyLength * 2, Allocator.Persistent);

            var qKeysPerMotions =
                from ma in motionData.pool.Motions.Select((x, i) => motionData.CreateAccessor(i))
                from ibone in Enumerable.Range(0, motionData.BoneLength)
                select(ma, ime: ibone, iparent: ma.GetParentBoneIndex(ibone))
            ;

            foreach (var(ma, ime, iparent) in qKeysPerMotions)
            {
                //if( iparent == -1 ) continue;
                if (iparent == -1)
                {
                }

                Debug.Log($"bone {ime} {iparent}");
                var thisPositions   = ma.GetStreamSlice(ime, KeyStreamSection.positions).Stream;
                var parentPositions = ma.GetStreamSlice(iparent, KeyStreamSection.positions).Stream;
                var thisRotations   = ma.GetStreamSlice(ime, KeyStreamSection.rotations).Stream;
                var parentRotations = ma.GetStreamSlice(iparent, KeyStreamSection.rotations).Stream;

                var posNearKeys = new StreamNearKeysCacheData();
                var posShifter  = new StreamKeyShiftData()
                {
                    Keys = parentPositions
                };
                var rotNearKeys = new StreamNearKeysCacheData();
                var rotShifter  = new StreamKeyShiftData()
                {
                    Keys = parentRotations
                };

                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisRotations.Length; i++)
                {
                    var thisRot = thisRotations[i];

                    rotNearKeys.TimeProgress = thisRot.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lrot = new quaternion(thisRot.Value);
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisRot.Value    = math.mul(prot, lrot).value;
                    thisRotations[i] = thisRot;
                    //	Debug.Log($"{thisRot.Time} {thisRot.Value}");
                }
            }
        }
        static public void TransformKeyDataToWorld_(this MotionDataInNative motionData)
        {
            var qKeysPerMotions =
                from ma in motionData.pool.Motions.Select((x, i) => motionData.CreateAccessor(i))
                from ibone in Enumerable.Range(0, motionData.BoneLength)
                select(ma, ime: ibone, iparent: ma.GetParentBoneIndex(ibone))
            ;

            foreach (var(ma, ime, iparent) in qKeysPerMotions)
            {
                if (iparent == -1)
                {
                    continue;
                }

                Debug.Log($"bone {ime} {iparent}");
                var thisPositions   = ma.GetStreamSlice(ime, KeyStreamSection.positions).Stream;
                var parentPositions = ma.GetStreamSlice(iparent, KeyStreamSection.positions).Stream;
                var thisRotations   = ma.GetStreamSlice(ime, KeyStreamSection.rotations).Stream;
                var parentRotations = ma.GetStreamSlice(iparent, KeyStreamSection.rotations).Stream;

                var posNearKeys = new StreamNearKeysCacheData();
                var posShifter  = new StreamKeyShiftData()
                {
                    Keys = parentPositions
                };
                var rotNearKeys = new StreamNearKeysCacheData();
                var rotShifter  = new StreamKeyShiftData()
                {
                    Keys = parentRotations
                };

                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisRotations.Length; i++)
                {
                    var thisRot = thisRotations[i];

                    rotNearKeys.TimeProgress = thisRot.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lrot = new quaternion(thisRot.Value);
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisRot.Value    = math.mul(prot, lrot).value;
                    thisRotations[i] = thisRot;
                    //	Debug.Log($"{thisRot.Time} {thisRot.Value}");
                }

                StreamExtentions.InitializeKeys(ref posNearKeys, ref posShifter);
                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisPositions.Length; i++)
                {
                    var thisPos = thisPositions[i];

                    posNearKeys.TimeProgress = thisPos.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref posNearKeys, ref posShifter);
                    }while(posNearKeys.TimeProgress > posNearKeys.Time_To);

                    rotNearKeys.TimeProgress = thisPos.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lpos = thisPos.Value.As_float3();
                    var ppos = posNearKeys.Interpolate(posNearKeys.CaluclateTimeNormalized());
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisPos.Value    = math.mul(prot, lpos).As_float4() + ppos;
                    thisPositions[i] = thisPos;
                    //Debug.Log( $"{thisPos.Time} {thisPos.Value}" );
                }
            }
        }