replay-viewer
Version:
Rocket League replay viewer React component and tooling
190 lines • 9.27 kB
JavaScript
import { Raycaster, SphereBufferGeometry, MeshBasicMaterial, Mesh, Vector3, BufferGeometry, LineBasicMaterial, Line, BufferAttribute, BoxBufferGeometry } from "three";
import { addCameraChangeListener, removeCameraChangeListener, } from "../eventbus/events/cameraChange";
import { addCanvasResizeListener, removeCanvasResizeListener, } from "../eventbus/events/canvasResize";
import SceneManager from "./SceneManager";
import CameraManager from "./CameraManager";
import { GameManager } from "./GameManager";
var DrawingManager = /** @class */ (function () {
function DrawingManager(_a) {
var _b = _a === void 0 ? {} : _a, color = _b.color, meshScale = _b.meshScale, drawObject = _b.drawObject, is3dMode = _b.is3dMode;
var _this = this;
this.isDrawing = false;
this.clearDrawings = function () {
_this.removeClones();
};
this.setColor = function (newColor) {
_this.color = newColor;
var meshMat = _this.drawableMeshes.sphere.material;
meshMat.color.set(newColor);
var lineMat = _this.drawableMeshes.line.material;
lineMat.color.set(newColor);
_this.isPaused() && _this.refreshFrame();
};
this.getDrawableMeshes = function () {
var basicMaterial = new MeshBasicMaterial({ color: _this.color });
var boxGeometry = new BoxBufferGeometry(0.2, 0.2, 0.2);
var box = new Mesh(boxGeometry, basicMaterial);
var sphereGeometry = new SphereBufferGeometry(0.1, 32, 32);
var sphere = new Mesh(sphereGeometry, basicMaterial);
var lineMaterial = new LineBasicMaterial({ color: _this.color });
var lineGeometry = new BufferGeometry();
var positions = new Float32Array(_this.MAX_POINTS * 3);
lineGeometry.setAttribute('position', new BufferAttribute(positions, 3));
var line = new Line(lineGeometry, lineMaterial);
_this.cloneArray.push(sphere.uuid, line.uuid, box.uuid);
return { box: box, sphere: sphere, line: line };
};
this.getCanvas = function () {
var domNode = GameManager.getInstance().getDOMNode();
var _a = domNode.getBoundingClientRect(), width = _a.width, height = _a.height;
return { domNode: domNode, width: width, height: height };
};
this.onMouseDown = function (_a) {
var offsetX = _a.offsetX, offsetY = _a.offsetY, ctrlKey = _a.ctrlKey, altKey = _a.altKey;
_this.handleDrawing(offsetX, offsetY);
_this.isDrawing = true;
};
this.onMouseMove = function (_a) {
var offsetX = _a.offsetX, offsetY = _a.offsetY, ctrlKey = _a.ctrlKey, altKey = _a.altKey;
if (_this.isDrawing) {
_this.handleDrawing(offsetX, offsetY);
}
};
this.onMouseUp = function (_a) {
var offsetX = _a.offsetX, offsetY = _a.offsetY, ctrlKey = _a.ctrlKey, altKey = _a.altKey;
_this.isDrawing = false;
};
this.getMouseVector = function (offsetX, offsetY) {
var cam = _this.activeCamera;
var scale = _this.canvas.width / 2;
var x = (offsetX / _this.canvas.width) * 2 - 1;
var y = -(offsetY / _this.canvas.height) * 2 + 1;
var rayCaster = new Raycaster();
rayCaster.setFromCamera({ x: x, y: y }, cam);
var rayDir = new Vector3(rayCaster.ray.direction.x * scale, rayCaster.ray.direction.y * scale, rayCaster.ray.direction.z * scale);
var rayVector = new Vector3(cam.position.x + rayDir.x, cam.position.y + rayDir.y, cam.position.z + rayDir.z);
if (_this.is3dMode) {
var intersections = rayCaster.intersectObjects([_this.field], true);
return intersections.length ? intersections[0].point : undefined;
}
return rayVector;
};
this.drawLine = function (offsetX, offsetY) {
var mouseVec = _this.getMouseVector(offsetX, offsetY);
if (!mouseVec)
return;
var index = _this.isDrawing ? _this.activeLinePointIndex : _this.activeLinePointIndex = 0;
var activeLine = _this.isDrawing ? _this.drawableMeshes.line : _this.drawableMeshes.line.clone();
if (!_this.isDrawing) {
activeLine.geometry = _this.drawableMeshes.line.geometry.clone();
_this.cloneArray.push(activeLine.uuid);
SceneManager.getInstance().scene.add(activeLine);
_this.drawableMeshes.line = activeLine;
}
var geo = activeLine.geometry;
var positionAttribute = geo.attributes.position;
var positions = positionAttribute.array;
positions[index * 3 + 0] = mouseVec.x;
positions[index * 3 + 1] = mouseVec.y;
positions[index * 3 + 2] = mouseVec.z;
geo.setDrawRange(0, ++_this.activeLinePointIndex);
positionAttribute.needsUpdate = true;
_this.isPaused() && _this.refreshFrame();
};
this.drawMesh = function (offsetX, offsetY, mesh) {
var rayVector = _this.getMouseVector(offsetX, offsetY);
if (rayVector) {
var clone = _this.drawableMeshes[mesh].clone();
_this.cloneArray.push(clone.uuid);
if (_this.is3dMode)
rayVector.y += (_this.meshScale * 0.1);
clone.position.copy(rayVector);
clone.scale.setScalar(_this.meshScale);
SceneManager.getInstance().scene.add(clone);
_this.isPaused() && _this.refreshFrame();
}
};
this.removeClones = function () {
var scene = SceneManager.getInstance().scene;
_this.cloneArray.map(function (i) {
var clone = scene.getObjectByProperty('uuid', i);
if (clone) {
clone.geometry.dispose(),
clone.material.dispose();
scene.remove(clone);
}
});
_this.isPaused() && _this.refreshFrame();
};
this.refreshFrame = function () {
window.requestAnimationFrame(function () {
var gameManager = GameManager.getInstance();
gameManager.render();
gameManager.clock.setFrame(gameManager.clock.currentFrame);
});
};
this.isPaused = function () {
return GameManager.getInstance().clock.isPaused();
};
this.updateSize = function (_a) {
var width = _a.width, height = _a.height;
_this.canvas.width = width;
_this.canvas.height = height;
};
this.onCameraChange = function (_a) {
var camera = _a.camera;
_this.activeCamera = camera;
};
this.color = color || "ff0000";
this.drawObject = drawObject || 'line';
this.is3dMode = is3dMode || false;
this.meshScale = meshScale || 200;
this.MAX_POINTS = 500;
this.field = SceneManager.getInstance().field.field;
this.activeCamera = CameraManager.getInstance().activeCamera;
this.canvas = this.getCanvas();
this.cloneArray = [];
this.activeLinePointIndex = 0;
this.drawableMeshes = this.getDrawableMeshes();
addCanvasResizeListener(this.updateSize);
addCameraChangeListener(this.onCameraChange);
this.canvas.domNode.addEventListener("mousedown", this.onMouseDown);
this.canvas.domNode.addEventListener("mousemove", this.onMouseMove);
this.canvas.domNode.addEventListener("mouseup", this.onMouseUp);
}
DrawingManager.prototype.handleDrawing = function (offsetX, offsetY) {
switch (this.drawObject) {
case 'line':
this.drawLine(offsetX, offsetY);
break;
default:
this.drawMesh(offsetX, offsetY, this.drawObject);
break;
}
};
DrawingManager.getInstance = function () {
if (!DrawingManager.instance) {
throw new Error("DrawingManager not initialized with call to `init`");
}
return DrawingManager.instance;
};
DrawingManager.init = function (state) {
DrawingManager.instance = new DrawingManager(state);
return DrawingManager.instance;
};
DrawingManager.destruct = function () {
var instance = DrawingManager.instance;
if (instance) {
removeCameraChangeListener(instance.onCameraChange);
removeCanvasResizeListener(instance.updateSize);
instance.removeClones();
instance.canvas.domNode.removeEventListener("mousedown", instance.onMouseDown);
instance.canvas.domNode.removeEventListener("mousemove", instance.onMouseMove);
instance.canvas.domNode.removeEventListener("mouseup", instance.onMouseUp);
DrawingManager.instance = undefined;
}
};
return DrawingManager;
}());
export default DrawingManager;
//# sourceMappingURL=DrawingManager.js.map