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()); }
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); }