SamplingTime GetOutputPlayTime(DebugMemory debugMemory, SamplingTime samplingTime, SamplingTime closestMatch, DebugIdentifier outputTimeIdentifier) { if (!closestMatch.IsValid) { return(samplingTime); } int playAtTimeTypeCode = BurstRuntime.GetHashCode32 <PlayAtTimeDebug>(); for (DebugReference reference = debugMemory.FirstOrDefault; reference.IsValid; reference = debugMemory.Next(reference)) { if (reference.identifier.typeHashCode != playAtTimeTypeCode) { continue; } PlayAtTimeDebug playAtTime = debugMemory.ReadObject <PlayAtTimeDebug>(reference); if (playAtTime.playTime.Equals(outputTimeIdentifier)) { return(closestMatch); } } return(samplingTime); }
public bool MatchPose(PoseSet candidates, SamplingTime samplingTime, MatchOptions options = MatchOptions.None, float maxPoseDeviation = -1.0f) { if ((options & MatchOptions.DontMatchIfCandidateIsPlaying) > 0 && IsTimeInSequences(samplingTime, candidates.sequences)) { if ((options & MatchOptions.LoopSegment) > 0) { LoopSegmentIfEndReached(samplingTime); } return(true); } DebugPushGroup(); SamplingTime closestMatch = FindClosestPoseMatch(candidates, samplingTime, maxPoseDeviation); if (closestMatch.IsValid) { PlayAtTime(closestMatch); return(true); } else { if ((options & MatchOptions.LoopSegment) > 0) { LoopSegmentIfEndReached(samplingTime); } return(false); } }
/// <summary> /// Reads a sampling time from the buffer. /// </summary> /// <returns>The sampling time that has been read from the buffer.</returns> public static SamplingTime ReadSamplingTime(this Buffer buffer) { var theta = buffer.ReadSingle(); var timeIndex = buffer.ReadTimeIndex(); return(SamplingTime.Create(timeIndex, theta)); }
public static float DrawFragment(ref MotionSynthesizer synthesizer, SamplingTime samplingTime, Color color, float timeOffset, AffineTransform anchorTransform) { Assert.IsTrue(samplingTime.IsValid); AnimationSampleTimeIndex animSampleTime = synthesizer.Binary.GetAnimationSampleTimeIndex(samplingTime.timeIndex); string animFrameTxt = $"{animSampleTime.clipName} frame {animSampleTime.animFrameIndex}"; ref Binary binary = ref synthesizer.Binary;
public float GetAverageTrajectorySpeed(SamplingTime samplingTime, float timeOffset) { float deltaTime = math.rcp(SampleRate); float trajectoryTimeSpan = deltaTime * 2.0f; return(math.length(GetTrajectoryVelocity(samplingTime, timeHorizon * timeOffset, trajectoryTimeSpan))); }
public void LoopSegmentIfEndReached(SamplingTime samplingTime) { int numSegmentFrames = Binary.GetSegment(samplingTime.segmentIndex).destination.NumFrames; if (samplingTime.frameIndex == numSegmentFrames - 1) { PlayAtTime(SamplingTime.Create(TimeIndex.Create(samplingTime.segmentIndex))); } }
internal static DeltaSamplingTime Create(SamplingTime samplingTime, AffineTransform deltaTransform, BlittableBool crossedBoundary) { return(new DeltaSamplingTime { crossedBoundary = crossedBoundary, samplingTime = samplingTime, deltaTransform = deltaTransform }); }
internal PoseFragment(ref Binary binary, MetricIndex metricIndex) { samplingTime = SamplingTime.Invalid; this.metricIndex = metricIndex; var numFeatures = GetNumFeatures(ref binary, metricIndex); array = new NativeArray <float3>(numFeatures, Allocator.Temp); }
public unsafe SamplingTime FindClosestPoseMatch(PoseSet candidates, SamplingTime samplingTime, float maxPoseDeviation = -1.0f) { if (!samplingTime.IsValid) { return(SamplingTime.Create(SelectFirstPose(candidates.sequences))); } ref Binary binary = ref Binary;
public string GetFragmentDebugText(SamplingTime samplingTime, string fragmentName, float speedTimeOffset = -1.0f) { AnimationSampleTimeIndex animSampleTime = GetAnimationSampleTimeIndex(samplingTime.timeIndex); if (!animSampleTime.IsValid) { return($"<b>{fragmentName}:</b> Invalid fragment"); } string speedText = speedTimeOffset >= 0.0f ? $", <b>Speed:</b> {GetAverageTrajectorySpeed(samplingTime, speedTimeOffset):0.000} m/s" : ""; return($"<b>{fragmentName}:</b> {animSampleTime.clipName}, <b>Frame:</b> {animSampleTime.animFrameIndex}{speedText}"); }
bool IsTimeInSequences(SamplingTime samplingTime, NativeArray <PoseSequence> sequences) { var numSequences = sequences.Length; for (int i = 0; i < sequences.Length; ++i) { Binary.SegmentIndex segmentIndex = Binary.GetInterval(sequences[i].intervalIndex).segmentIndex; if (samplingTime.segmentIndex == segmentIndex) { return(true); } } return(false); }
public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options) { if (!playTime.IsValid) { return; } SamplingTime samplingTime = debugMemory.ReadObjectFromIdentifier <SamplingTime>(playTime); string text = synthesizer.Binary.GetFragmentDebugText(samplingTime, "Play Clip", options.timeOffset); DebugDraw.SetMovableTextTitle(options.textWindowIdentifier, "Play At Time"); DebugDraw.AddMovableTextLine(options.textWindowIdentifier, text, options.inputOutputFragTextColor); DebugDraw.DrawFragment(ref synthesizer, samplingTime, options.inputOutputFragmentColor, options.timeOffset, synthesizer.WorldRootTransform); }
public void Update(AffineTransform worldRootTransform, SamplingTime samplingTime, float deltaTime) { Assert.IsTrue(samplingTime.IsValid); // // Sample target pose into temporary buffer // var targetPose = SamplePoseAt(samplingTime); // // Trigger transition if requested // TriggerTransition(ref targetPose.Ref, previousDeltaTime); ref var binary = ref Binary;
/// <summary> /// Switches the pose generation stream to read /// from the sampling time passed as argument. /// </summary> /// <remarks> /// Animation poses are always generated continuously /// based on a time index. This method allows to switch /// to a new starting time. The motion synthesizer automatically /// handles any discrepancies between the old and the new pose. /// </remarks> /// <param name="samplingTime">New sampling time for the pose generation.</param> public void PlayAtTime(SamplingTime samplingTime) { DebugWriteBlittableObject(ref samplingTime); PlayAtTimeDebug playAtTimeDebug = new PlayAtTimeDebug() { playTime = samplingTime.debugIdentifier }; DebugWriteBlittableObject(ref playAtTimeDebug); samplingTime.debugIdentifier = DebugIdentifier.Invalid; if (updateInProgress) { delayedPushTime = samplingTime.timeIndex; } else { ref Binary binary = ref Binary; if (!binary.IsValid(samplingTime)) { throw new ArgumentException("Invalid sampling time passed as argument"); } if (!Time.timeIndex.Equals(samplingTime.timeIndex)) { this.samplingTime = samplingTime; poseGenerator.TriggerTransition(); } Assert.IsTrue(binary.IsValid(Time)); lastSamplingTime = TimeIndex.Invalid; }
/// <summary> /// Advances a sampling time by a certain amount of time. /// </summary> /// <remarks> /// This method advances a starting time by a certain amount of time. /// <para> /// It is valid to pass a negative delta time in order to step /// backward in time. /// </para> /// <para> /// The resulting time can belong to a different segment if boundary /// clips have been configured for the segment that the initial time /// belongs to. /// </para> /// <para> /// The resulting new sampling time will be clamped at segment boundaries /// if no boundary clips have been defined for the segment that the initial time belongs to. /// </para> /// </remarks> /// <param name="samplingTime">The reference time to advance from.</param> /// <param name="deltaTime">The time increment to advance by in seconds.</param> /// <returns>The resulting sampling time.</returns> public DeltaSamplingTime Advance(SamplingTime samplingTime, float deltaTime) { ref var segment = ref GetSegment(samplingTime.segmentIndex);
/// <summary> /// Switches the pose generation stream to read /// from the time index passed as argument. /// </summary> /// <remarks> /// Animation poses are always generated continuously /// based on a sampling time. This method allows to switch /// to a new starting time. The motion synthesizer automatically /// handles any discrepancies between the old and the new pose. /// </remarks> /// <param name="timeIndex">New starting time index for the pose generation.</param> public void PlayAtTime(TimeIndex timeIndex) { PlayAtTime( SamplingTime.Create( timeIndex, Time.theta)); }
internal string GetFragmentDebugText(ref MotionSynthesizer synthesizer, string fragmentName, SamplingTime time, float timeOffset, ref DeviationTable deviationTable, bool addCost = true) { Assert.IsTrue(time.IsValid); string text = synthesizer.Binary.GetFragmentDebugText(time, fragmentName, timeOffset); if (!addCost) { return(text); } string costInfo = GetCostInformation(ref synthesizer.Binary, ref deviationTable, time); if (!string.IsNullOrEmpty(costInfo)) { text = text + costInfo; } return(text); }
public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options) { ref var binary = ref synthesizer.Binary;
string GetCostInformation(ref Binary binary, ref DeviationTable deviationTable, SamplingTime samplingTime) { if (!deviationTable.IsValid || !samplingTime.IsValid) { return(""); } DeviationScore deviation = deviationTable.GetDeviation(ref binary, samplingTime.timeIndex); if (!deviation.IsValid) { return($"\nThis fragment wasn't considered during the query"); } if (deviation.trajectoryDeviation >= 0.0f) { return($"\n<b>Pose cost:</b> {deviation.poseDeviation:0.000}, <b>Trajectory:</b> {deviation.trajectoryDeviation:0.000}, <b>Total:</b> {deviation.poseDeviation + deviation.trajectoryDeviation:0.000}"); } else { return($"\n<b>Pose cost:</b> {deviation.poseDeviation:0.000}"); } }
public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options) { DrawPath(); }
public bool MatchPoseAndTrajectory(PoseSet candidates, SamplingTime samplingTime, Trajectory trajectory, MatchOptions options = MatchOptions.None, float trajectoryWeight = 0.6f, float minTrajectoryDeviation = 0.03f, float maxTotalDeviation = -1.0f) { if ((options & MatchOptions.DontMatchIfCandidateIsPlaying) > 0 && IsTimeInSequences(samplingTime, candidates.sequences)) { if ((options & MatchOptions.LoopSegment) > 0) { LoopSegmentIfEndReached(samplingTime); } return(true); } if (!trajectory.debugIdentifier.IsValid) { DebugPushGroup(); DebugWriteUnblittableObject(ref trajectory); } DebugWriteUnblittableObject(ref candidates); DebugWriteBlittableObject(ref samplingTime); SamplingTime closestMatch = FindClosestPoseAndTrajectoryMatch(candidates, samplingTime, trajectory, trajectoryWeight, maxTotalDeviation); if (closestMatch.IsValid) { bool validMatch = true; if (minTrajectoryDeviation >= 0.0f) { float trajectoryDeviation = RelativeDeviation(closestMatch.timeIndex, trajectory); validMatch = trajectoryDeviation >= minTrajectoryDeviation; SamplingTime outputTime = closestMatch; outputTime.debugIdentifier = DebugIdentifier.Invalid; DebugWriteBlittableObject(ref outputTime, true); TrajectoryHeuristicDebug heuristicDebug = new TrajectoryHeuristicDebug() { desiredTrajectory = trajectory.debugIdentifier, candidate = samplingTime.debugIdentifier, closestMatch = closestMatch.debugIdentifier, outputTime = outputTime.debugIdentifier, trajectoryDeviation = trajectoryDeviation, minTrajectoryDeviation = minTrajectoryDeviation }; DebugWriteBlittableObject(ref heuristicDebug); closestMatch = outputTime; } if (validMatch) { PlayAtTime(closestMatch); return(true); } } if ((options & MatchOptions.LoopSegment) > 0) { LoopSegmentIfEndReached(samplingTime); } return(false); }
public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options) { int fragmentSlot = 0; DebugDraw.SetMovableTextTitle(options.textWindowIdentifier, DebugWindowTitle); DeviationTable deviationTable = this.deviationTable.IsValid ? debugMemory.ReadObjectFromIdentifier <DeviationTable>(this.deviationTable) : DeviationTable.CreateInvalid(); SamplingTime samplingTime = GetSamplingTime(debugMemory, this.samplingTime); if (samplingTime.IsValid) { if ((options.drawFlags & DebugDrawFlags.InputFragment) > 0) { DebugDraw.DrawFragment(ref synthesizer, samplingTime, options.inputOutputFragmentColor, options.timeOffset, synthesizer.WorldRootTransform); ++fragmentSlot; } DebugDraw.AddMovableTextLine(options.textWindowIdentifier, GetFragmentDebugText(ref synthesizer, "Input Clip", samplingTime, options.timeOffset, ref deviationTable), options.inputOutputFragTextColor); } SamplingTime closestMatch = GetSamplingTime(debugMemory, this.closestMatch); DebugIdentifier outputTimeIdentifier = this.closestMatch; if (closestMatch.IsValid) { if ((options.drawFlags & DebugDrawFlags.BestFragment) > 0) { DebugDraw.DrawFragment(ref synthesizer, closestMatch, options.bestFragmentColor, options.timeOffset, GetAnchor(synthesizer.WorldRootTransform, fragmentSlot++ *options.distanceOffset, camera)); DebugDraw.AddMovableTextLine(options.textWindowIdentifier, GetFragmentDebugText(ref synthesizer, "Best Match Fragment", closestMatch, options.timeOffset, ref deviationTable), options.bestFragTextColor); if (maxDeviation >= 0.0f) { string deviationMsg = GetDeviationText(); DebugDraw.AddMovableTextLine(options.textWindowIdentifier, deviationMsg, options.bestFragTextColor); } Nullable <TrajectoryHeuristicDebug> trajectoryHeuristic = FindTrajectoryHeuristic(debugMemory); if (trajectoryHeuristic.HasValue) { trajectoryHeuristic.Value.DrawDebugText(ref options); outputTimeIdentifier = trajectoryHeuristic.Value.outputTime; } } } SamplingTime outputTime = GetOutputPlayTime(debugMemory, samplingTime, closestMatch, outputTimeIdentifier); if ((options.drawFlags & DebugDrawFlags.OutputFragment) > 0) { DebugDraw.DrawFragment(ref synthesizer, outputTime, options.inputOutputFragmentColor, options.timeOffset, GetAnchor(synthesizer.WorldRootTransform, fragmentSlot++ *options.distanceOffset, camera)); DebugDraw.AddMovableTextLine(options.textWindowIdentifier, GetFragmentDebugText(ref synthesizer, "Output Clip", outputTime, options.timeOffset, ref deviationTable, false), options.inputOutputFragTextColor); } if (debugSamplingTime.IsValid) { if ((options.drawFlags & DebugDrawFlags.SelectedFragment) > 0) { int slot = fragmentSlot > 0 ? -1 : 0; DebugDraw.DrawFragment(ref synthesizer, debugSamplingTime, options.selectedFragmentColor, options.timeOffset, GetAnchor(synthesizer.WorldRootTransform, slot * options.distanceOffset, camera)); DebugDraw.AddMovableTextLine(options.textWindowIdentifier, GetFragmentDebugText(ref synthesizer, "Selected Clip", debugSamplingTime, options.timeOffset, ref deviationTable), options.selectedFragTextColor); } } deviationTable.Dispose(); if ((options.drawFlags & DebugDrawFlags.Trajectory) > 0 && this.trajectory.IsValid) { using (Trajectory trajectory = debugMemory.ReadObjectFromIdentifier <Trajectory>(this.trajectory)) { Binary.TrajectoryFragmentDisplay.Options trajectoryOptions = Binary.TrajectoryFragmentDisplay.Options.Create(); DebugExtensions.DebugDrawTrajectory(synthesizer.WorldRootTransform, trajectory, synthesizer.Binary.SampleRate, options.inputTrajectoryColor, options.inputTrajectoryColor, trajectoryOptions.showForward); } } }
/// <summary> /// Writes a sampling time to the buffer. /// </summary> /// <param name="samplingTime">The sampling time that should be written to the buffer.</param> public static void Write(this Buffer buffer, SamplingTime samplingTime) { buffer.Write(samplingTime.theta); buffer.Write(samplingTime.timeIndex); }