From 11c00e1af771042e887b1152eb7aa5af63ce5ae5 Mon Sep 17 00:00:00 2001 From: Daan Vanden Bosch Date: Wed, 24 Jul 2019 15:48:39 +0200 Subject: [PATCH] Fixed bug that would let the camera pan when pressing arrow keys anywhere. --- package.json | 2 +- src/rendering/Renderer.ts | 67 +++++++++++++++++++++++--------- src/rendering/TextureRenderer.ts | 3 +- src/ui/RendererComponent.tsx | 9 ++++- yarn.lock | 10 ++--- 5 files changed, 64 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index da82cb2c..705a64e7 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@types/react-virtualized-select": "^3.0.7", "@types/text-encoding": "^0.0.35", "antd": "^3.20.1", + "camera-controls": "^1.12.2", "craco-antd": "^1.11.0", "golden-layout": "^1.5.9", "javascript-lp-solver": "^0.4.5", @@ -29,7 +30,6 @@ "react-virtualized-select": "^3.1.3", "text-encoding": "^0.7.0", "three": "^0.106.2", - "three-orbit-controls": "^82.1.0", "typescript": "~3.4.5" }, "scripts": { diff --git a/src/rendering/Renderer.ts b/src/rendering/Renderer.ts index c963107b..6ee2320a 100644 --- a/src/rendering/Renderer.ts +++ b/src/rendering/Renderer.ts @@ -1,20 +1,27 @@ +import CameraControls from "camera-controls"; import * as THREE from "three"; import { - Camera, Color, Group, HemisphereLight, - MOUSE, + OrthographicCamera, + PerspectiveCamera, Scene, Vector2, Vector3, WebGLRenderer, + Clock, } from "three"; -import OrbitControlsCreator from "three-orbit-controls"; -const OrbitControls = OrbitControlsCreator(THREE); +CameraControls.install({ + // Hack to make panning and orbiting work the way we want. + THREE: { + ...THREE, + MOUSE: { ...THREE.MOUSE, LEFT: THREE.MOUSE.RIGHT, RIGHT: THREE.MOUSE.LEFT }, + }, +}); -export class Renderer { +export class Renderer { protected _debug = false; get debug(): boolean { @@ -26,13 +33,15 @@ export class Renderer { } readonly camera: C; - readonly controls: any; + readonly controls: CameraControls; readonly scene = new Scene(); readonly light_holder = new Group(); private renderer = new WebGLRenderer({ antialias: true }); private render_scheduled = false; + private render_stop_scheduled = false; private light = new HemisphereLight(0xffffff, 0x505050, 1.2); + private controls_clock = new Clock(); constructor(camera: C) { this.camera = camera; @@ -41,10 +50,9 @@ export class Renderer { this.dom_element.addEventListener("mousedown", this.on_mouse_down); this.dom_element.style.outline = "none"; - this.controls = new OrbitControls(camera, this.dom_element); - this.controls.mouseButtons.ORBIT = MOUSE.RIGHT; - this.controls.mouseButtons.PAN = MOUSE.LEFT; - this.controls.addEventListener("change", this.schedule_render); + this.controls = new CameraControls(camera, this.renderer.domElement); + this.controls.dampingFactor = 1; + this.controls.draggingDampingFactor = 1; this.scene.background = new Color(0x181818); this.light_holder.add(this.light); @@ -69,17 +77,27 @@ export class Renderer { return coords; } + start_rendering(): void { + requestAnimationFrame(this.call_render); + } + + stop_rendering(): void { + this.render_stop_scheduled = true; + } + schedule_render = () => { - if (!this.render_scheduled) { - this.render_scheduled = true; - requestAnimationFrame(this.call_render); - } + this.render_scheduled = true; }; reset_camera(position: Vector3, look_at: Vector3): void { - this.controls.reset(); - this.camera.position.copy(position); - this.camera.lookAt(look_at); + this.controls.setLookAt( + position.x, + position.y, + position.z, + look_at.x, + look_at.y, + look_at.z + ); } protected render(): void { @@ -91,7 +109,20 @@ export class Renderer { }; private call_render = () => { + const controls_updated = this.controls.update(this.controls_clock.getDelta()); + const should_render = this.render_scheduled || controls_updated; + this.render_scheduled = false; - this.render(); + + if (this.render_stop_scheduled) { + this.render_stop_scheduled = false; + return; + } + + if (should_render) { + this.render(); + } + + requestAnimationFrame(this.call_render); }; } diff --git a/src/rendering/TextureRenderer.ts b/src/rendering/TextureRenderer.ts index 1641a130..564cbde1 100644 --- a/src/rendering/TextureRenderer.ts +++ b/src/rendering/TextureRenderer.ts @@ -29,7 +29,8 @@ export class TextureRenderer extends Renderer { constructor() { super(new OrthographicCamera(-400, 400, 300, -300, 1, 10)); - this.controls.enableRotate = false; + this.controls.azimuthRotateSpeed = 0; + this.controls.polarRotateSpeed = 0; autorun(() => { this.scene.remove(...this.quad_meshes); diff --git a/src/ui/RendererComponent.tsx b/src/ui/RendererComponent.tsx index 90bf8c62..9d665fbb 100644 --- a/src/ui/RendererComponent.tsx +++ b/src/ui/RendererComponent.tsx @@ -1,9 +1,9 @@ import React, { Component, ReactNode } from "react"; -import { Camera } from "three"; +import { OrthographicCamera, PerspectiveCamera } from "three"; import { Renderer } from "../rendering/Renderer"; type Props = { - renderer: Renderer; + renderer: Renderer; width: number; height: number; debug?: boolean; @@ -25,7 +25,12 @@ export class RendererComponent extends Component { } } + componentDidMount(): void { + this.props.renderer.start_rendering(); + } + componentWillUnmount(): void { + this.props.renderer.stop_rendering(); this.props.on_will_unmount && this.props.on_will_unmount(); } diff --git a/yarn.lock b/yarn.lock index 101728e6..f6d3e12a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2636,6 +2636,11 @@ camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camera-controls@^1.12.2: + version "1.12.2" + resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-1.12.2.tgz#02ae544256f93964e27c6e4b2cc5887cff417d3f" + integrity sha512-+qXGiyEwaDIBMT2eDdzaAL0Ihik0yitSdGF5tzGIHwwNFfcYQQTxNacc7EPuMAMgQkF6Opg8m8Uy3IfifaCLMg== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -10422,11 +10427,6 @@ text-table@0.2.0, text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -three-orbit-controls@^82.1.0: - version "82.1.0" - resolved "https://registry.yarnpkg.com/three-orbit-controls/-/three-orbit-controls-82.1.0.tgz#11a7f33d0a20ecec98f098b37780f6537374fab4" - integrity sha1-EafzPQog7OyY8Jizd4D2U3N0+rQ= - three@^0.106.2: version "0.106.2" resolved "https://registry.yarnpkg.com/three/-/three-0.106.2.tgz#6752d304c470e4df230944ecd45325e7bf79e1f8"