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); }
void ResetAnimationSampler() { DisableDisplayTrajectory(); clip = null; sourceAvatar = null; if (clipAssetCallbacks != null) { clipAssetCallbacks.Dispose(); clipAssetCallbacks = null; } if (sampler != null) { sampler.Dispose(); sampler = null; } previousTime = -1.0f; }
bool InitAnimationSampler(TaggedAnimationClip clip) { this.clip = clip; if (clipAssetCallbacks != null) { clipAssetCallbacks.Dispose(); } AnimationClip animationClip = clip.GetOrLoadClipSync(); clipAssetCallbacks = new AssetPostprocessCallbacks(animationClip); clipAssetCallbacks.importDelegate = OnClipReimport; clipAssetCallbacks.deleteDelegate = OnClipDelete; sourceAvatar = clip.RetargetSourceAvatar; if (sampler != null) { sampler.Dispose(); sampler = null; } try { sampler = new AnimationSampler(targetRig, animationClip); } catch (Exception e) { Debug.LogError(e.Message); return(false); } previousTime = -1.0f; return(true); }
public IEnumerator BuildTransforms() { // // Now re-sample all animations according to the target // sample rate and adjust the segment information to // reference the transforms array. // // // Calculate total number of poses to be generated // (based on previously generated segments) // int numJoints = rig.NumJoints; if (numJoints < 2) { throw new ArgumentException($"Rig does not have enough joints. Only {numJoints} present."); } if (numFrames == 0) { throw new Exception("No animation frame to process, please make sure there is at least one single non-empty tag in your Kinematica asset."); } int numTransforms = numFrames * numJoints; using (NativeArray <AffineTransform> transforms = new NativeArray <AffineTransform>(numTransforms, Allocator.Persistent)) { int globalSegmentIndex = 0; int destinationFrameIndex = 0; for (int clipIndex = 0; clipIndex < clipSegments.Count; ++clipIndex) { ClipSegments segments = clipSegments[clipIndex]; AnimationClip clip = segments.Clip.GetOrLoadClipSync(); using (AnimationSampler animSampler = new AnimationSampler(rig, clip)) { float sourceSampleRate = clip.frameRate; float targetSampleRate = asset.SampleRate; float sampleRateRatio = sourceSampleRate / targetSampleRate; int numFrameResampledClip = (int)math.ceil(targetSampleRate * segments.Clip.DurationInSeconds); for (int segmentIndex = 0; segmentIndex < segments.NumSegments; ++segmentIndex, ++globalSegmentIndex) { Segment segment = segments[segmentIndex]; int firstFrame = Missing.roundToInt(segment.source.FirstFrame / sampleRateRatio); firstFrame = math.min(firstFrame, numFrameResampledClip - 1); SampleRange sampleRange = new SampleRange() { startFrameIndex = firstFrame, numFrames = segment.destination.NumFrames }; using (AnimationSampler.RangeSampler rangeSampler = animSampler.PrepareRangeSampler(asset.SampleRate, sampleRange, destinationFrameIndex, transforms)) { rangeSampler.Schedule(); progressFeedback?.Invoke(new ProgressInfo() { title = $"Sample clip {clip.name}", progress = (float)globalSegmentIndex / numSegments }); while (!rangeSampler.IsComplete) { yield return(null); if (bCancel) { rangeSampler.Complete(); yield break; } } rangeSampler.Complete(); } destinationFrameIndex += segment.destination.NumFrames; } } } WriteTransformsToBinary(transforms); } }