public KeyframeAnimation AllocateCopyAtFixedSampleRate(float sampleRate)
        {
            int numJoints = jointSamplers.Length;

            KeyframeAnimation anim = new KeyframeAnimation();

            anim.animationCurves = new List <CurveInfo>(animationCurves.Count);
            anim.jointSamplers   = new NativeArray <TransformSampler>(numJoints, Allocator.Persistent);
            anim.numFrames       = (int)math.ceil(sampleRate * duration);

            for (int jointIndex = 0; jointIndex < numJoints; ++jointIndex)
            {
                TransformSampler sourceSampler      = jointSamplers[jointIndex];
                TransformSampler destinationSampler = TransformSampler.CreateEmpty(sourceSampler.DefaultTransform);

                for (int curveIndex = 0; curveIndex < TransformSampler.NumCurves; ++curveIndex)
                {
                    if (sourceSampler.GetCurveProxy(curveIndex).HasCurve)
                    {
                        Curve curve = new Curve(anim.numFrames, Allocator.Persistent); // fixed framerate curve
                        anim.animationCurves.Add(new CurveInfo()
                        {
                            curve      = curve,
                            jointIndex = jointIndex,
                            curveIndex = curveIndex,
                        });
                        destinationSampler.SetCurve(curveIndex, curve);
                    }
                }

                anim.jointSamplers[jointIndex] = destinationSampler;
            }

            return(anim);
        }
        public static KeyframeAnimation Create(AnimationSampler animSampler, AnimationClip animationClip)
        {
            KeyframeAnimation anim = new KeyframeAnimation();

            anim.InitWithRigTransforms(animSampler.TargetRig);
            anim.duration  = Utility.ComputeAccurateClipDuration(animationClip);
            anim.numFrames = 0;

            var bindings = AnimationUtility.GetCurveBindings(animationClip);

            foreach (EditorCurveBinding binding in bindings)
            {
                int jointIndex = animSampler.TargetRig.GetJointIndexFromPath(binding.path);

                if (jointIndex >= 0)
                {
                    var curve = AnimationUtility.GetEditorCurve(animationClip, binding);

                    if (jointIndex == 0 && animationClip.hasMotionCurves)
                    {
                        if (binding.propertyName.Contains("Motion"))
                        {
                            anim.MapEditorCurve(jointIndex, binding.propertyName, "MotionT", "MotionQ", curve);
                        }
                    }
                    else if (jointIndex == 0 && animationClip.hasRootCurves)
                    {
                        if (binding.propertyName.Contains("Root"))
                        {
                            anim.MapEditorCurve(jointIndex, binding.propertyName, "RootT", "RootQ", curve);
                        }
                    }
                    else
                    {
                        anim.MapEditorCurve(jointIndex, binding.propertyName, "m_LocalPosition", "m_LocalRotation", curve);
                    }
                }
            }

            anim.animationCurves.Sort((x, y) => x.CompareTo(y));

            return(anim);
        }
        internal AnimationSampler(AnimationRig targetRig, AnimationClip animationClip)
        {
            this.targetRig = targetRig;

            this.animationClip = animationClip;

            int numJoints = targetRig.NumJoints;

            editorAnimation = KeyframeAnimation.Create(this, animationClip);
            bakedAnimation  = null;

            try
            {
                poseSamplePostProcess = new PoseSamplePostProcess(targetRig, animationClip, editorAnimation.JointSamplers[0][0]);
            }
            catch (Exception e)
            {
                editorAnimation.Dispose();
                throw e;
            }
        }