Beispiel #1
0
    private void DoPlayback()
    {
        int nPoints    = history.Count;
        int ivMinIndex = 0;
        int ivMaxIndex = nPoints - 2; // -1 because indices; -1 because there is one less intervals than points.

        if (ivMaxIndex >= 0)
        {
            float timeNow             = LocalTime.Value;
            int?  properIntervalIndex = null;
            while (true)
            {
                int pivotIndex = (ivMinIndex + ivMaxIndex) / 2;
                HistoryDataPoint pivotBound1 = history[pivotIndex];
                HistoryDataPoint pivotBound2 = history[pivotIndex + 1];

                if (IsCurrentInterval(pivotBound1, pivotBound2))
                {
                    // Check the pivot interval. If it matches, exit the loop
                    properIntervalIndex = pivotIndex;
                    break;
                }
                else if (ivMinIndex != ivMaxIndex)
                {
                    // There are more intervals to explore, let's split the search space either on the left or right
                    bool checkLeft = (TimeDirectionSign * (timeNow - pivotBound1.Time) < 0);
                    if (checkLeft && ivMinIndex == pivotIndex || !checkLeft && ivMaxIndex == pivotIndex)
                    {
                        LogError($"Failed to locate the interval for local time {timeNow} in the history.");
                        break;
                    }
                    else
                    {
                        if (checkLeft)
                        {
                            ivMaxIndex = pivotIndex - 1;
                        }
                        else
                        {
                            ivMinIndex = pivotIndex + 1;
                        }
                    }
                }
                else
                {
                    LogError("Unable to locate the interval where a value should be taken in the history.");
                    break;
                }
            }

            if (properIntervalIndex.HasValue)
            {
                // Get the position and rotation to apply
                HistoryDataPoint p1            = history[properIntervalIndex.Value];
                HistoryDataPoint p2            = history[properIntervalIndex.Value + 1];
                float            intervalRatio = GetUnboundedRatioInInterval(p1, p2);
                HistoryDataPoint interpolation = HistoryDataPoint.Lerp(p1, p2, intervalRatio);

                LogDebug($"Applying saved point: {interpolation}");

                // Apply these to the object
                var rb = GetTargetRigidbody();
                rb.MovePosition(interpolation.Position);
                rb.MoveRotation(interpolation.Angle);

                // Discard things that were played back
                while (history.Count > properIntervalIndex.Value + 2)
                {
                    history.RemoveAt(history.Count - 1);
                }
            }
        }
        else
        {
            LogError(
                "Unable to playback an (almost) empty history. This action should have maybe be completed by now.\n" +
                $"  * History times = [{history.Aggregate("", (s, p) => (string.IsNullOrEmpty(s) ? s : s + ", ") + p.Time.ToString())}], " +
                $"time now = {LocalTime}.");
        }
    }