UNPKG

replay-viewer

Version:

Rocket League replay viewer React component and tooling

188 lines 8.57 kB
import { OrthographicCamera, PerspectiveCamera, Vector3 } from "three"; import { ABOVE_FIELD_CAMERA, BLUE_GOAL_CAMERA, FREE_CAMERA, ORANGE_GOAL_CAMERA, ORTHOGRAPHIC, } from "../constants/gameObjectNames"; import { dispatchCameraChange } from "../eventbus/events/cameraChange"; import { dispatchCameraFrameUpdate } from "../eventbus/events/cameraFrameUpdate"; import { addCanvasResizeListener, removeCanvasResizeListener, } from "../eventbus/events/canvasResize"; import { addFrameListener, removeFrameListener } from "../eventbus/events/frame"; import { addKeyControlListener, applyDirections, removeKeyControlListener, } from "../eventbus/events/keyControl"; import { isOrthographicCamera } from "../operators/isOrthographicCamera"; import SceneManager from "./SceneManager"; var CameraManager = /** @class */ (function () { function CameraManager() { var _this = this; this.updateSize = function (_a) { var width = _a.width, height = _a.height; _this.width = width; _this.height = height; _this.updateCameraSize(); }; this.update = function () { var position = SceneManager.getInstance().ball.ball.position; dispatchCameraFrameUpdate({ ballPosition: position, ballCam: _this.ballCam, isUsingBoost: false, activeCamera: _this.activeCamera }); if (!isOrthographicCamera(_this.activeCamera)) { _this.activeCamera.lookAt(position); } }; this.onKeyControl = function (_a) { var directions = _a.directions, speed = _a.speed; if (_this.activeCamera.name === FREE_CAMERA) { var cameraDirection = new Vector3(); _this.activeCamera.getWorldDirection(cameraDirection); var multiplier = speed ? 75 : 15; var newDirection = applyDirections(cameraDirection, directions, multiplier); var newPosition = new Vector3(); newPosition.copy(_this.activeCamera.position); newPosition.add(newDirection); // Don't allow phasing inside of the ball var ballPosition = SceneManager.getInstance().ball.ball.position; if (ballPosition.distanceTo(newPosition) < 200) { return; } // Don't allow cameras under the field if (newPosition.y < 10) { newPosition.setY(10); } // If all checks pass, set the new position _this.activeCamera.position.copy(newPosition); _this.update(); dispatchCameraChange({ camera: _this.activeCamera }); } }; this.activeCamera = SceneManager.getInstance().field.getCamera(ORANGE_GOAL_CAMERA); this.defaultCamera = this.activeCamera; this.width = 640; this.height = 480; this.ballCam = true; this.activeCamera.position.z = 5000; this.activeCamera.position.y = 750; addFrameListener(this.update); addCanvasResizeListener(this.updateSize); addKeyControlListener(this.onKeyControl); } CameraManager.prototype.toggleBallCam = function () { this.ballCam = !this.ballCam; this.update(); }; CameraManager.prototype.setCameraLocation = function (_a) { var playerName = _a.playerName, fieldLocation = _a.fieldLocation; var _b = SceneManager.getInstance(), players = _b.players, field = _b.field; if (playerName) { var player = players.find(function (p) { return p.playerName === playerName; }); if (player) { this.setActiveCamera(player.camera); } } else if (fieldLocation) { switch (fieldLocation) { case "orange": this.setActiveCamera(field.getCamera(ORANGE_GOAL_CAMERA)); break; case "blue": this.setActiveCamera(field.getCamera(BLUE_GOAL_CAMERA)); break; case "center": this.setActiveCamera(field.getCamera(ABOVE_FIELD_CAMERA)); break; case "freecam": var freecam = field.getCamera(FREE_CAMERA); if (!isOrthographicCamera(this.activeCamera)) { if (freecam.parent) { freecam.parent.updateMatrixWorld(); } freecam.position.setFromMatrixPosition(this.activeCamera.matrixWorld); freecam.rotation.fromArray(this.activeCamera.rotation.toArray()); } this.setActiveCamera(freecam); break; case "orthographic-above-field": this.setActiveCamera(field.getCamera(ORTHOGRAPHIC.ABOVE_FIELD)); break; case "orthographic-orange-left": this.setActiveCamera(field.getCamera(ORTHOGRAPHIC.ORANGE_LEFT)); break; case "orthographic-orange-right": this.setActiveCamera(field.getCamera(ORTHOGRAPHIC.ORANGE_RIGHT)); break; case "orthographic-blue-left": this.setActiveCamera(field.getCamera(ORTHOGRAPHIC.BLUE_LEFT)); break; case "orthographic-blue-right": this.setActiveCamera(field.getCamera(ORTHOGRAPHIC.BLUE_RIGHT)); break; default: this.setActiveCamera(this.defaultCamera); } } // Dispatch to all manager listeners dispatchCameraChange({ camera: this.activeCamera }); }; CameraManager.prototype.updateCameraSize = function () { var _a = this, camera = _a.activeCamera, width = _a.width, height = _a.height; if (camera instanceof PerspectiveCamera) { camera.aspect = width / height; camera.updateProjectionMatrix(); } else if (camera instanceof OrthographicCamera) { /** * Here, we are computing the zoom of the camera given the aspect ratio. For cameras with an * aspect ratio greater than 4:3, we base the zoom on the height. Otherwise, we use width. The * minimum zoom should always be 0.02. * * The zoom when based on the height is a simple linear function y = x / 12500 + 0.01, where x * is the new height and y is the desired zoom. * * The denominator of the width-based computation is simply the slope of the previous * function, 12500, multiplied by 1.3 since this is aspect ratio breaking point we have set in * the if statement. */ if (width / height > 1.3) { var newZoom = height / 12500 + 0.01; camera.zoom = Math.max(newZoom, 0.02); } else { var newZoom = width / 16250 + 0.01; camera.zoom = Math.max(newZoom, 0.02); } camera.left = -width / 2; camera.right = width / 2; camera.top = height / 2; camera.bottom = -height / 2; camera.updateProjectionMatrix(); } }; CameraManager.prototype.setActiveCamera = function (camera) { if (!camera) { return; } this.activeCamera = camera; this.updateCameraSize(); this.update(); }; CameraManager.getInstance = function () { if (!CameraManager.instance) { throw new Error("CameraManager not initialized with call to `init`"); } return CameraManager.instance; }; CameraManager.init = function () { CameraManager.instance = new CameraManager(); return CameraManager.instance; }; CameraManager.destruct = function () { var instance = CameraManager.instance; if (instance) { removeFrameListener(instance.update); removeCanvasResizeListener(instance.updateSize); removeKeyControlListener(instance.onKeyControl); CameraManager.instance = undefined; } }; return CameraManager; }()); export default CameraManager; //# sourceMappingURL=CameraManager.js.map