/// <summary> /// Setup binding between character joints and animator stream, that will be written by Kinematica job /// </summary> /// <param name="animator">Unity animator associated with the animation job</param> /// <param name="transforms">Character joint transforms</param> /// <param name="synthesizer">Reference to motion synthesizer</param> /// <param name="deltaTimePropertyHandle">Property handle for the deltaTime</param> /// <returns></returns> public bool Setup(Animator animator, Transform[] transforms, ref MotionSynthesizer synthesizer, PropertySceneHandle deltaTimePropertyHandle) { this.synthesizer = MemoryRef <MotionSynthesizer> .Create(ref synthesizer); int numJoints = synthesizer.Binary.numJoints; this.transforms = new NativeArray <TransformStreamHandle>(numJoints, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); boundJoints = new NativeArray <bool>(numJoints, Allocator.Persistent, NativeArrayOptions.ClearMemory); // Root joint is always first transform, and names don't need to match contrary to other joints this.transforms[0] = animator.BindStreamTransform(transforms[0]); boundJoints[0] = true; for (int i = 1; i < transforms.Length; i++) { int jointNameIndex = synthesizer.Binary.GetStringIndex(transforms[i].name); int jointIndex = (jointNameIndex >= 0) ? synthesizer.Binary.animationRig.GetJointIndexForNameIndex(jointNameIndex) : -1; if (jointIndex >= 0) { this.transforms[jointIndex] = animator.BindStreamTransform(transforms[i]); boundJoints[jointIndex] = true; } } deltaTime = deltaTimePropertyHandle; return(true); }
public static TrajectoryPrediction CreateFromDirection(ref MotionSynthesizer synthesizer, float3 desiredDirection, float desiredSpeed, Trajectory trajectory, float velocityFactor, float rotationFactor) { float3 desiredVelocity = desiredDirection * desiredSpeed; quaternion desiredRotation = Missing.forRotation(Missing.forward, desiredDirection); return(Create(ref synthesizer, desiredVelocity, desiredRotation, trajectory, velocityFactor, rotationFactor)); }
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;
static void ExecuteSelf <T>(ref T self, ref MotionSynthesizer synthesizer) where T : Trait { // // TODO: Unfortunately Burst doesn't accept instance methods // or generics when calling 'CompileFunctionPointer'... // // var executeThis = typeof(TraitType).GetMethod( // nameof(ExecuteSelf), BindingFlags.Static | BindingFlags.NonPublic); // var genericExecuteThis = executeThis.MakeGenericMethod(typeof(T)); // self.Execute(ref synthesizer); }
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); }
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) { DrawPath(); }
public void GenerateTrajectory(ref MotionSynthesizer synthesizer, ref Trajectory trajectory) { if (GoalReached) { return; } Assert.IsTrue(trajectory.Length > 0); if (trajectory.Length == 0) { return; } AffineTransform rootTransform = synthesizer.WorldRootTransform; float maxSpeedAtCorner = navParams.desiredSpeed; if (nextControlPoint < pathSpline.segments.Length - 1) { float3 curSegmentDir = pathSpline.segments[nextControlPoint].SegmentDirection; float3 nextSegmentDir = pathSpline.segments[nextControlPoint + 1].SegmentDirection; float alignment = math.max(math.dot(curSegmentDir, nextSegmentDir), 0.0f); maxSpeedAtCorner = math.lerp(navParams.maxSpeedAtRightAngle, navParams.desiredSpeed, alignment); } int halfTrajectoryLength = trajectory.Length / 2; float deltaTime = synthesizer.Binary.TimeHorizon / halfTrajectoryLength; float distance = 0.0f; float speed = math.length(synthesizer.CurrentVelocity); float remainingDistOnSpline = pathSpline.ComputeCurveLength(nextControlPoint); float remainingDistOnSegment = pathSpline.segments[nextControlPoint].CurveLength; for (int index = halfTrajectoryLength; index < trajectory.Length; ++index) { if (remainingDistOnSpline > 0.0f) { // acceleration to reach desired speed float acceleration = math.clamp((navParams.desiredSpeed - speed) / deltaTime, -navParams.maximumDeceleration, navParams.maximumAcceleration); // decelerate if needed to reach maxSpeedAtCorner float brakingDistance = 0.0f; if (remainingDistOnSegment > 0.0f && speed > maxSpeedAtCorner) { brakingDistance = NavigationParams.ComputeDistanceToReachSpeed(speed, maxSpeedAtCorner, -navParams.maximumDeceleration); if (remainingDistOnSegment <= brakingDistance) { acceleration = math.min(acceleration, NavigationParams.ComputeAccelerationToReachSpeed(speed, maxSpeedAtCorner, remainingDistOnSegment)); } } // decelerate if needed to stop when last control point is reached brakingDistance = NavigationParams.ComputeDistanceToReachSpeed(speed, 0.0f, -navParams.maximumDeceleration); if (remainingDistOnSpline <= brakingDistance) { acceleration = math.min(acceleration, NavigationParams.ComputeAccelerationToReachSpeed(speed, 0.0f, remainingDistOnSpline)); } speed += acceleration * deltaTime; } else { speed = 0.0f; } float moveDist = speed * deltaTime; remainingDistOnSegment -= moveDist; remainingDistOnSpline -= moveDist; distance += moveDist; AffineTransform point = EvaluatePointAtDistance(distance); trajectory[index] = rootTransform.inverseTimes(point); } synthesizer.DebugPushGroup(); synthesizer.DebugWriteUnblittableObject(ref trajectory); outputTrajectory = trajectory.debugIdentifier; synthesizer.DebugWriteUnblittableObject(ref this); }
/// <summary> /// Creates a trajectory prediction instance. /// </summary> /// <param name="synthesizer">Reference to the motion synthesizer to generate the trajectory for.</param> /// <param name="desiredLinearVelocity">Desired linear velocity in meters per second in character space.</param> /// <param name="desiredRotation">Desired orientation in character space.</param> /// <param name="trajectory">Memory array that the generated trajectory should be written to.</param> /// <param name="velocityFactor">Factor that determines when the desired velocity w.r.t. the time horizon should be reached.</param> /// <param name="rotationFactor">Factor that determines when the desired rotation w.r.t. the time horizon should be reached.</param> /// <param name="currentLinearVelocity">Current linear velocity in meters per second in character space</param> /// <returns>The newly created trajectory prediction instance.</returns> public static TrajectoryPrediction Create(ref MotionSynthesizer synthesizer, float3 desiredLinearVelocity, quaternion desiredRotation, Trajectory trajectory, float velocityFactor, float rotationFactor, float3 currentLinearVelocity) { ref var binary = ref synthesizer.Binary;
/// <summary> /// Creates a trajectory prediction instance. /// </summary> /// <param name="synthesizer">Reference to the motion synthesizer to generate the trajectory for.</param> /// <param name="desiredLinearVelocity">Desired linear velocity in meters per second in character space.</param> /// <param name="desiredRotation">Desired orientation in character space.</param> /// <param name="trajectory">Memory array that the generated trajectory should be written to.</param> /// <param name="velocityFactor">Factor that determines when the desired velocity w.r.t. the time horizon should be reached.</param> /// <param name="rotationFactor">Factor that determines when the desired rotation w.r.t. the time horizon should be reached.</param> /// <returns>The newly created trajectory prediction instance.</returns> public static TrajectoryPrediction Create(ref MotionSynthesizer synthesizer, float3 desiredLinearVelocity, quaternion desiredRotation, Trajectory trajectory, float velocityFactor, float rotationFactor) { return(TrajectoryPrediction.Create(ref synthesizer, desiredLinearVelocity, desiredRotation, trajectory, velocityFactor, rotationFactor, synthesizer.CurrentVelocity)); }
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); } } }
public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options) { ref var binary = ref synthesizer.Binary;
public SegmentTooShortException(ref MotionSynthesizer synthesizer, int segmentIndex) { m_Synthesizer = MemoryRef <MotionSynthesizer> .Create(ref synthesizer); m_SegmentIndex = segmentIndex; }