UNPKG

replay-viewer

Version:

Rocket League replay viewer React component and tooling

147 lines 5.29 kB
import { dispatchFrameEvent } from "../eventbus/events/frame"; /** * This clock provides a simple callback system that keeps track of elapsed and delta time * transformations. This makes it extremely easy to parse the deltas of a replay by their frame * count, and maintain a real-time comparison against those frames. Primarily to be used by the * THREE.js animation system and communicate changes back to the parent container of animations so * that we can display data which is recorded at a frame and not at a time. * * When constructing this object, you should provide an array of elapsed durations*1000, where each * index in the array represents the time in milliseconds since the beginning of the animation. The * first index, 0, should be set to 0 (the elapsed time since the start), followed by these times. * * For example: * 0: 0 * 1: 483.877919614315 * 2: 838.5848999023438 * 3: 1322.4628567695618 * 4: 1809.6305429935455 */ var FPSClock = /** @class */ (function () { function FPSClock(frameToDuration) { this.frameToDuration = frameToDuration; this.paused = true; this.deltaQueue = []; this.elapsedTime = 0; this.currentFrame = 0; this.lastDelta = 0; this.update = this.update.bind(this); this.timeout(); } FPSClock.prototype.reset = function () { this.setFrame(0); }; FPSClock.prototype.setFrame = function (frame) { // Prevent negative frames frame = frame < 0 ? 0 : frame; var diff = this.frameToDuration[frame] - this.frameToDuration[this.currentFrame]; this.deltaQueue.push(diff); this.currentFrame = frame; this.doCallbacks(); }; FPSClock.prototype.isPaused = function () { return this.paused; }; FPSClock.prototype.play = function () { if (this.paused) { this.lastDelta = performance.now(); this.paused = false; this.timeout(); } }; FPSClock.prototype.pause = function () { this.paused = true; this.doCallbacks(); this.timeout(false); }; /** * Returns the elapsed time in milliseconds. */ FPSClock.prototype.getElapsedTime = function () { return this.frameToDuration[this.currentFrame]; }; /** * Returns the number of seconds elapsed since the last time getDelta was called. This function * uses a combination of the performance.now() functionality when animations are rolling, * combined with a small queue of delta modifications made by the setFrame function. This will * allow us to apply delta factors quite easily and in one spot (i.e. 2x speed) as opposed to * scattering arithmetic throughout the code. * * @returns {number} seconds */ FPSClock.prototype.getDelta = function () { var now = performance.now(); // Initialize empty delta if (!this.lastDelta) { this.lastDelta = now; } // Only apply "now" when not paused if (!this.paused) { this.deltaQueue.push(now - this.lastDelta); } this.lastDelta = now; // Process every delta contributer var delta = 0; while (this.deltaQueue.length) { var time = this.deltaQueue.pop(); if (time) { delta += time; } } // Use the elapsed deltas for bookkeeping this.elapsedTime += delta; return delta / 1000; }; FPSClock.prototype.update = function () { if (!this.paused) { this.getElapsedFrames(); this.doCallbacks(); } }; FPSClock.prototype.getElapsedFrames = function () { if (this.currentFrame >= this.frameToDuration.length - 1) { this.pause(); } if (this.frameToDuration[this.currentFrame] >= this.elapsedTime) { this.currentFrame = 0; } while (this.frameToDuration[this.currentFrame + 1] < this.elapsedTime) { this.currentFrame += 1; } }; FPSClock.prototype.timeout = function (enable) { if (enable === void 0) { enable = true; } if (enable) { this.animation = setInterval(this.update, 1000 / 60); } else if (this.animation) { clearInterval(this.animation); } }; FPSClock.prototype.doCallbacks = function () { dispatchFrameEvent({ delta: this.getDelta(), frame: this.currentFrame, elapsedTime: this.getElapsedTime(), }); }; /** * Note that the final frame is ignored when considering the elapsed time per frame. If we * considered this final delta, we would need a frame to "animate to". * * @param data Contains frame delta information */ FPSClock.convertReplayToClock = function (data) { var elapsedTime = 0; var frames = data.frames.map(function (frameInfo) { var retValue = elapsedTime; var delta = frameInfo[0] * 1000; elapsedTime += delta; return retValue; }); return new FPSClock(frames); }; return FPSClock; }()); export default FPSClock; //# sourceMappingURL=FPSClock.js.map