[881] | 1 | "use strict"; |
---|
| 2 | import * as THREE from 'three'; |
---|
| 3 | |
---|
| 4 | const OrbitControls = require('three-orbit-controls')(THREE); |
---|
| 5 | |
---|
| 6 | /** |
---|
| 7 | * Class for creating camera object in THREE.js view. it uses OrbitControls for |
---|
| 8 | * user moving. It is designed to work with model analysis. |
---|
| 9 | */ |
---|
| 10 | class Camera { |
---|
| 11 | /** |
---|
| 12 | * Method for Camera initialization. It's adjusting the view according to |
---|
| 13 | * camera resize, prepares OrbitControls as default controller. |
---|
| 14 | */ |
---|
| 15 | init() { |
---|
| 16 | this.perspectiveCamera = new THREE.PerspectiveCamera( |
---|
| 17 | this.config.fieldOfView, |
---|
| 18 | window.innerWidth / window.innerHeight, |
---|
| 19 | this.config.near, |
---|
| 20 | this.config.far |
---|
| 21 | ); |
---|
| 22 | this.perspectiveCamera.up.set(0,0,1); |
---|
| 23 | this.cameraControl = new OrbitControls(this.perspectiveCamera, this.rendererDOMElement); |
---|
| 24 | this.cameraControl.autoRotate = this.autoRotate; |
---|
| 25 | this.cameraControl.autoRotateSpeed = this.config.autoRotateSpeed; |
---|
| 26 | this.cameraControl.enableKeys = false; |
---|
| 27 | } |
---|
| 28 | |
---|
| 29 | /** |
---|
| 30 | * Creates instance of camera, then initalizes it with init() method |
---|
| 31 | * @param {{fieldOfView: number, near: number, far: number}} config Configuration of Camera view |
---|
| 32 | * @param {Element} rendererDOMElement Canvas in which element will be drawn. |
---|
| 33 | * @param {boolean} autoRotate true if camera should rotate, false otherwise |
---|
| 34 | */ |
---|
| 35 | constructor(config, rendererDOMElement, autoRotate) { |
---|
| 36 | this.config = config; |
---|
| 37 | this.rendererDOMElement = rendererDOMElement; |
---|
| 38 | this.autoRotate = autoRotate; |
---|
| 39 | this.perspectiveCamera = null; |
---|
| 40 | this.cameraControl = null; |
---|
| 41 | this.init(); |
---|
| 42 | } |
---|
| 43 | |
---|
| 44 | /** |
---|
| 45 | * Method for updating modelBox coordinates |
---|
| 46 | * @param {{min: {x: number, y: number, z: number}, max: {x: number, y: number, z: number}}} modelBox Bounding box of Model |
---|
| 47 | * @param {{min: {x: number, y: number, z: number}, max: {x: number, y: number, z: number}}} box update of bounding box |
---|
| 48 | */ |
---|
| 49 | updateModelBox(modelBox, box) { |
---|
| 50 | modelBox.min.x = Math.min( modelBox.min.x, box.min.x ); |
---|
| 51 | modelBox.min.y = Math.min( modelBox.min.y, box.min.y ); |
---|
| 52 | modelBox.min.z = Math.min( modelBox.min.z, box.min.z ); |
---|
| 53 | |
---|
| 54 | modelBox.max.x = Math.max( modelBox.max.x, box.max.x ); |
---|
| 55 | modelBox.max.y = Math.max( modelBox.max.y, box.max.y ); |
---|
| 56 | modelBox.max.z = Math.max( modelBox.max.z, box.max.z ); |
---|
| 57 | } |
---|
| 58 | |
---|
| 59 | /** |
---|
| 60 | * Extracts bounding box of given object. |
---|
| 61 | * @param {Object3D} object object for which bounding box is extracted |
---|
| 62 | * @returns {Box3} bounding box of object |
---|
| 63 | */ |
---|
| 64 | getBoundingBox(object) { |
---|
| 65 | let box = new THREE.Box3(); |
---|
| 66 | box.setFromObject(object); |
---|
| 67 | return box; |
---|
| 68 | } |
---|
| 69 | |
---|
| 70 | /** |
---|
| 71 | * Calculates Camera position and rotation that should be used in order to see all meshes in scene. |
---|
| 72 | * @param {Mesh[]} meshes list of meshes to be bound by camera. |
---|
| 73 | * @returns {{target: {x: number, y: number, z: number}, position: {x: number, y: number, z: number}}} new position of Camera and target, to which Camera should point |
---|
| 74 | */ |
---|
| 75 | calculateCameraSetting(meshes) { |
---|
| 76 | if (meshes.length == 0) { |
---|
| 77 | return this.config.defaultSettings; |
---|
| 78 | } |
---|
| 79 | |
---|
| 80 | let modelBox = new THREE.Box3(); |
---|
| 81 | for (let i = 0; i < meshes.length; i++) { |
---|
| 82 | let mesh = meshes[i]; |
---|
| 83 | let box = this.getBoundingBox(mesh); |
---|
| 84 | this.updateModelBox(modelBox, box); |
---|
| 85 | } |
---|
| 86 | |
---|
| 87 | let modelSphere = modelBox.getBoundingSphere(); |
---|
| 88 | |
---|
[911] | 89 | this.targetPosition = modelSphere.center.clone(); |
---|
| 90 | this.cameraPosition = modelSphere.center.clone().addScalar(modelSphere.radius); |
---|
| 91 | |
---|
[881] | 92 | return { |
---|
| 93 | target: { |
---|
| 94 | x: modelSphere.center.x, |
---|
| 95 | y: modelSphere.center.y, |
---|
| 96 | z: modelSphere.center.z |
---|
| 97 | }, |
---|
| 98 | position: { |
---|
| 99 | x: modelSphere.center.x + modelSphere.radius, |
---|
| 100 | y: modelSphere.center.y + modelSphere.radius, |
---|
| 101 | z: modelSphere.center.z + modelSphere.radius |
---|
| 102 | } |
---|
| 103 | }; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | /** |
---|
| 107 | * Moves Camera to cover all selected meshes in canvas. |
---|
| 108 | * @param {Mesh[]} meshes list of meshes to be seen |
---|
| 109 | */ |
---|
| 110 | zoomAll(meshes) { |
---|
| 111 | let settings = this.calculateCameraSetting(meshes); |
---|
| 112 | this.cameraControl.target.set(settings.target.x, settings.target.y, settings.target.z); |
---|
| 113 | this.perspectiveCamera.position.set(settings.position.x, settings.position.y, settings.position.z); |
---|
| 114 | this.cameraControl.update(); |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | /** |
---|
| 118 | * Getter for THREE.js perspective camera logic. |
---|
| 119 | * @returns {PerspectiveCamera} reference to Camera perspective camera |
---|
| 120 | */ |
---|
| 121 | getPerspectiveCamera() { |
---|
| 122 | return this.perspectiveCamera; |
---|
| 123 | } |
---|
| 124 | |
---|
| 125 | /** |
---|
| 126 | * Getter for THREE.js orbit controls logic. |
---|
| 127 | * @returns {OrbitControls} reference to Camera orbit controls |
---|
| 128 | */ |
---|
| 129 | getCameraControl() { |
---|
| 130 | return this.cameraControl; |
---|
| 131 | } |
---|
| 132 | |
---|
| 133 | /** |
---|
| 134 | * Sets the camera autorotation property. |
---|
| 135 | * @param {boolean} autoRotate true if camera should autorotate, false otherwise |
---|
| 136 | */ |
---|
| 137 | setAutoRotate(autoRotate) { |
---|
| 138 | this.autoRotate = autoRotate; |
---|
| 139 | this.cameraControl.autoRotate = this.autoRotate; |
---|
| 140 | } |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | export default Camera; |
---|