/// <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);
        }
Ejemplo n.º 2
0
        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;
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 7
0
 public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options)
 {
     DrawPath();
 }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
 /// <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;
Ejemplo n.º 10
0
 /// <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);
                }
            }
        }
Ejemplo n.º 12
0
 public void Draw(Camera camera, ref MotionSynthesizer synthesizer, DebugMemory debugMemory, SamplingTime debugSamplingTime, ref DebugDrawOptions options)
 {
     ref var binary = ref synthesizer.Binary;
Ejemplo n.º 13
0
        public SegmentTooShortException(ref MotionSynthesizer synthesizer, int segmentIndex)
        {
            m_Synthesizer = MemoryRef <MotionSynthesizer> .Create(ref synthesizer);

            m_SegmentIndex = segmentIndex;
        }