public void Smooths_Velocity()
        {
            var input = new[]
            {
                new PathStepDefinition {
                    F = 5, X = 4, Y = -4, In = 2, Out = 2
                },                                                            // fc == -4
                new PathStepDefinition {
                    F = 1, X = 16, Y = 16
                },
            };

            var result = _transformer.TransformPath(input);

            var expected = new OutputPathStepInfo[]
            {
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 1, VelocityY = -1
                },
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 3, VelocityY = -3
                },
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 4, VelocityY = -4
                },                                                                               // Correct speed
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 7, VelocityY = 1
                },
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 13, VelocityY = 11
                },
                new OutputPathStepInfo {
                    FrameCount = 1, VelocityX = 16, VelocityY = 16
                },
            };

            CollectionAssert.AreEqual(expected.ToStringCollection(), result.ToStringCollection());
        }
Example #2
0
        public IEnumerable <OutputPathStepInfo> ProcessPath(IEnumerable <OutputPathStepInfo> steps)
        {
            short curVx    = 0;
            short curVy    = 0;
            short curFrame = 0;
            PathInstructionDefinition curInstruction = PathInstructionDefinition.Delta;
            string emitLabel = null;
            var    output    = new List <OutputPathStepInfo>();

            var endCode = new OutputPathStepInfo {
                VelocityY = 0, VelocityX = 0, FrameCount = 0, Instruction = PathInstructionDefinition.End
            };

            foreach (var step in steps.Concat(new[]
            {
                endCode
            }))
            {
                if (step.VelocityX != curVx || step.VelocityY != curVy || !string.IsNullOrWhiteSpace(step.Label) || step.Instruction != curInstruction)
                {
                    if (curInstruction == PathInstructionDefinition.Delta)
                    {
                        if (curFrame > 0)
                        {
                            while (curFrame > 0)
                            {
                                var emitCount = (short)Math.Min((long)curFrame, 255);
                                output.Add(
                                    new OutputPathStepInfo
                                {
                                    FrameCount  = (byte)emitCount,
                                    VelocityX   = curVx,
                                    VelocityY   = curVy,
                                    Label       = emitLabel,
                                    Instruction = curInstruction,
                                });
                                emitLabel = null;
                                curFrame -= emitCount;
                            }
                        }
                    }
                    else
                    {
                        output.Add(
                            new OutputPathStepInfo
                        {
                            FrameCount  = (short)curFrame,
                            VelocityX   = curVx,
                            VelocityY   = curVy,
                            Label       = emitLabel,
                            Instruction = curInstruction,
                        });
                    }

                    curFrame       = step.FrameCount;
                    curVx          = step.VelocityX;
                    curVy          = step.VelocityY;
                    curInstruction = step.Instruction;
                    emitLabel      = step.Label;
                }
                else
                {
                    curFrame += step.FrameCount;
                }
            }

            // Get list of labels
            var offset = 0;
            var labels = new Dictionary <string, int>();

            foreach (var step in output)
            {
                if (step.Instruction != PathInstructionDefinition.Jump &&
                    !string.IsNullOrWhiteSpace(step.Label))
                {
                    labels.Add(step.Label, offset);
                }
                offset += PathsProcessor.PathStructSize;
            }

            // Process jump instructions
            offset = 0;
            foreach (var step in output)
            {
                try
                {
                    if (step.Instruction == PathInstructionDefinition.Jump)
                    {
                        var jumpOffset = labels[step.Label] - offset;
                        step.FrameCount = 0;
                        step.VelocityX  = 0;
                        step.VelocityY  = 0;
                        step.Label      = null;
                        step.JumpDelta  = (short)jumpOffset;
                    }
                }
                catch
                {
                    throw new ConversionException($"Cannot find label {step.Label} for path jump");
                }

                offset += PathsProcessor.PathStructSize;
            }

            output.Add(endCode);
            return(output);
        }