| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070 |
- /*!
- * camera-controls
- * https://github.com/yomotsu/camera-controls
- * (c) 2017 @yomotsu
- * Released under the MIT License.
- */
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global = global || self, global.CameraControls = factory());
- }(this, function () { 'use strict';
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (typeof call === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- // based on https://github.com/mrdoob/eventdispatcher.js/
- var EventDispatcher =
- /*#__PURE__*/
- function () {
- function EventDispatcher() {
- _classCallCheck(this, EventDispatcher);
- this._listeners = {};
- }
- _createClass(EventDispatcher, [{
- key: "addEventListener",
- value: function addEventListener(type, listener) {
- var listeners = this._listeners;
- if (listeners[type] === undefined) {
- listeners[type] = [];
- }
- if (listeners[type].indexOf(listener) === -1) {
- listeners[type].push(listener);
- }
- }
- }, {
- key: "hasEventListener",
- value: function hasEventListener(type, listener) {
- var listeners = this._listeners;
- return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1;
- }
- }, {
- key: "removeEventListener",
- value: function removeEventListener(type, listener) {
- var listeners = this._listeners;
- var listenerArray = listeners[type];
- if (listenerArray !== undefined) {
- var index = listenerArray.indexOf(listener);
- if (index !== -1) {
- listenerArray.splice(index, 1);
- }
- }
- }
- }, {
- key: "dispatchEvent",
- value: function dispatchEvent(event) {
- var listeners = this._listeners;
- var listenerArray = listeners[event.type];
- if (listenerArray !== undefined) {
- event.target = this;
- var array = listenerArray.slice(0);
- for (var i = 0, l = array.length; i < l; i++) {
- array[i].call(this, event);
- }
- }
- }
- }]);
- return EventDispatcher;
- }();
- var THREE;
- var _AXIS_Y;
- var _v2;
- var _v3A;
- var _v3B;
- var _v3C;
- var _v4;
- var _xColumn;
- var _yColumn;
- var _sphericalA;
- var _sphericalB;
- var EPSILON = 0.001;
- var PI_2 = Math.PI * 2;
- var STATE = {
- NONE: -1,
- ROTATE: 0,
- DOLLY: 1,
- TRUCK: 2,
- TOUCH_ROTATE: 3,
- TOUCH_DOLLY_TRUCK: 4,
- TOUCH_TRUCK: 5
- };
- var CameraControls =
- /*#__PURE__*/
- function (_EventDispatcher) {
- _inherits(CameraControls, _EventDispatcher);
- _createClass(CameraControls, null, [{
- key: "install",
- value: function install(libs) {
- THREE = libs.THREE;
- _AXIS_Y = new THREE.Vector3(0, 1, 0);
- _v2 = new THREE.Vector2();
- _v3A = new THREE.Vector3();
- _v3B = new THREE.Vector3();
- _v3C = new THREE.Vector3();
- _v4 = new THREE.Vector4();
- _xColumn = new THREE.Vector3();
- _yColumn = new THREE.Vector3();
- _sphericalA = new THREE.Spherical();
- _sphericalB = new THREE.Spherical();
- }
- }]);
- function CameraControls(camera, domElement) {
- var _this;
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- _classCallCheck(this, CameraControls);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(CameraControls).call(this));
- _this._camera = camera;
- _this._yAxisUpSpace = new THREE.Quaternion().setFromUnitVectors(_this._camera.up, _AXIS_Y);
- _this._yAxisUpSpaceInverse = _this._yAxisUpSpace.clone().inverse();
- _this._state = STATE.NONE;
- _this.enabled = true;
- if (_this._camera.isPerspectiveCamera) {
- // How far you can dolly in and out ( PerspectiveCamera only )
- _this.minDistance = 0;
- _this.maxDistance = Infinity;
- } else if (_this._camera.isOrthographicCamera) {
- // How far you can zoom in and out ( OrthographicCamera only )
- _this.minZoom = 0;
- _this.maxZoom = Infinity;
- }
- _this.minPolarAngle = 0; // radians
- _this.maxPolarAngle = Math.PI/2; // radians /2 keeps it from going below horizion.
- _this.minAzimuthAngle = -Infinity; // radians
- _this.maxAzimuthAngle = Infinity; // radians
- // Target cannot move outside of this box
- _this._boundary = new THREE.Box3(new THREE.Vector3(-Infinity, -Infinity, -Infinity), new THREE.Vector3(Infinity, Infinity, Infinity));
- _this.boundaryFriction = 0.0;
- _this._boundaryEnclosesCamera = false;
- _this.dampingFactor = 0.05;
- _this.draggingDampingFactor = 0.25;
- _this.azimuthRotateSpeed = 1.0;
- _this.polarRotateSpeed = 1.0;
- _this.dollySpeed = 1.0;
- _this.truckSpeed = 2.0;
- _this.dollyToCursor = false;
- _this.verticalDragToForward = false;
- _this._domElement = domElement;
- _this._viewport = null; // the location of focus, where the object orbits around
- _this._target = new THREE.Vector3();
- _this._targetEnd = new THREE.Vector3(); // rotation
- _this._spherical = new THREE.Spherical().setFromVector3(_this._camera.position.clone().applyQuaternion(_this._yAxisUpSpace));
- _this._sphericalEnd = _this._spherical.clone(); // reset
- _this._target0 = _this._target.clone();
- _this._position0 = _this._camera.position.clone();
- _this._zoom0 = _this._camera.zoom;
- _this._dollyControlAmount = 0;
- _this._dollyControlCoord = new THREE.Vector2();
- _this._hasUpdated = true;
- _this.update(0);
- if (!_this._domElement || options.ignoreDOMEventListeners) {
- _this._removeAllEventListeners = function () {};
- } else {
- var extractClientCoordFromEvent = function extractClientCoordFromEvent(event, out) {
- out.set(0, 0);
- if (isTouchEvent(event)) {
- for (var i = 0; i < event.touches.length; i++) {
- out.x += event.touches[i].clientX;
- out.y += event.touches[i].clientY;
- }
- out.x /= event.touches.length;
- out.y /= event.touches.length;
- return out;
- } else {
- out.set(event.clientX, event.clientY);
- return out;
- }
- };
- var onMouseDown = function onMouseDown(event) {
- if (!scope.enabled) return;
- event.preventDefault();
- var prevState = scope._state;
- //changed to match CURA
- switch (event.button) {
- case THREE.MOUSE.LEFT:
- scope._state = STATE.TRUCK;
- break;
- case THREE.MOUSE.MIDDLE:
- scope._state = STATE.TRUCK;
- //scope._state = STATE.DOLLY;
- break;
- case THREE.MOUSE.RIGHT:
- scope._state = STATE.ROTATE;
- break;
- }
- if (prevState !== scope._state) {
- startDragging(event);
- }
- };
- var onTouchStart = function onTouchStart(event) {
- if (!scope.enabled) return;
- event.preventDefault();
- var prevState = scope._state;
- switch (event.touches.length) {
- case 1:
- // one-fingered touch: rotate
- scope._state = STATE.TOUCH_ROTATE;
- break;
- case 2:
- // two-fingered touch: dolly
- scope._state = STATE.TOUCH_DOLLY_TRUCK;
- break;
- case 3:
- // three-fingered touch: truck
- scope._state = STATE.TOUCH_TRUCK;
- break;
- }
- if (prevState !== scope._state) {
- startDragging(event);
- }
- };
- var onMouseWheel = function onMouseWheel(event) {
- if (!scope.enabled) return;
- event.preventDefault(); // Ref: https://github.com/cedricpinson/osgjs/blob/00e5a7e9d9206c06fdde0436e1d62ab7cb5ce853/sources/osgViewer/input/source/InputSourceMouse.js#L89-L103
- var mouseDeltaFactor = 120;
- var deltaYFactor = navigator.platform.indexOf('Mac') === 0 ? -1 : -3;
- var delta;
- if (event.wheelDelta !== undefined) {
- delta = event.wheelDelta / mouseDeltaFactor;
- } else if (event.deltaMode === 1) {
- delta = event.deltaY / deltaYFactor;
- } else {
- delta = event.deltaY / (10 * deltaYFactor);
- }
- var x, y;
- if (scope.dollyToCursor) {
- elementRect = scope._getClientRect(_v4);
- x = (event.clientX - elementRect.x) / elementRect.z * 2 - 1;
- y = (event.clientY - elementRect.y) / elementRect.w * -2 + 1;
- }
- dollyInternal(-delta, x, y);
- };
- var onContextMenu = function onContextMenu(event) {
- if (!scope.enabled) return;
- event.preventDefault();
- };
- var startDragging = function startDragging(event) {
- if (!scope.enabled) return;
- event.preventDefault();
- extractClientCoordFromEvent(event, _v2);
- elementRect = scope._getClientRect(_v4);
- dragStart.copy(_v2);
- if (scope._state === STATE.TOUCH_DOLLY_TRUCK) {
- // 2 finger pinch
- var dx = _v2.x - event.touches[1].clientX;
- var dy = _v2.y - event.touches[1].clientY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- dollyStart.set(0, distance); // center coords of 2 finger truck
- var x = (event.touches[0].clientX + event.touches[1].clientX) * 0.5;
- var y = (event.touches[0].clientY + event.touches[1].clientY) * 0.5;
- dragStart.set(x, y);
- }
- document.addEventListener('mousemove', dragging, {
- passive: false
- });
- document.addEventListener('touchmove', dragging, {
- passive: false
- });
- document.addEventListener('mouseup', endDragging);
- document.addEventListener('touchend', endDragging);
- scope.dispatchEvent({
- type: 'controlstart',
- originalEvent: event
- });
- };
- var dragging = function dragging(event) {
- if (!scope.enabled) return;
- event.preventDefault();
- extractClientCoordFromEvent(event, _v2);
- var deltaX = dragStart.x - _v2.x;
- var deltaY = dragStart.y - _v2.y;
- dragStart.copy(_v2);
- switch (scope._state) {
- case STATE.ROTATE:
- case STATE.TOUCH_ROTATE:
- var theta = PI_2 * scope.azimuthRotateSpeed * deltaX / elementRect.z;
- var phi = PI_2 * scope.polarRotateSpeed * deltaY / elementRect.w;
- scope.rotate(theta, phi, true);
- break;
- case STATE.DOLLY:
- // not implemented
- break;
- case STATE.TOUCH_DOLLY_TRUCK:
- var dx = _v2.x - event.touches[1].clientX;
- var dy = _v2.y - event.touches[1].clientY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- var dollyDelta = dollyStart.y - distance;
- var touchDollyFactor = 8;
- var dollyX = scope.dollyToCursor ? (dragStart.x - elementRect.x) / elementRect.z * 2 - 1 : 0;
- var dollyY = scope.dollyToCursor ? (dragStart.y - elementRect.y) / elementRect.w * -2 + 1 : 0;
- dollyInternal(dollyDelta / touchDollyFactor, dollyX, dollyY);
- dollyStart.set(0, distance);
- truckInternal(deltaX, deltaY);
- break;
- case STATE.TRUCK:
- case STATE.TOUCH_TRUCK:
- truckInternal(deltaX, deltaY);
- break;
- }
- scope.dispatchEvent({
- type: 'control',
- originalEvent: event
- });
- };
- var endDragging = function endDragging(event) {
- if (!scope.enabled) return;
- scope._state = STATE.NONE;
- document.removeEventListener('mousemove', dragging, {
- passive: false
- });
- document.removeEventListener('touchmove', dragging, {
- passive: false
- });
- document.removeEventListener('mouseup', endDragging);
- document.removeEventListener('touchend', endDragging);
- scope.dispatchEvent({
- type: 'controlend',
- originalEvent: event
- });
- };
- var truckInternal = function truckInternal(deltaX, deltaY) {
- if (scope._camera.isPerspectiveCamera) {
- var offset = _v3A.copy(scope._camera.position).sub(scope._target); // half of the fov is center to top of screen
- var fovInRad = scope._camera.fov * THREE.Math.DEG2RAD;
- var targetDistance = offset.length() * Math.tan(fovInRad / 2);
- var truckX = scope.truckSpeed * deltaX * targetDistance / elementRect.w;
- var pedestalY = scope.truckSpeed * deltaY * targetDistance / elementRect.w;
- if (scope.verticalDragToForward) {
- scope.truck(truckX, 0, true);
- scope.forward(-pedestalY, true);
- } else {
- scope.truck(truckX, pedestalY, true);
- }
- } else if (scope._camera.isOrthographicCamera) {
- // orthographic
- var _truckX = deltaX * (scope._camera.right - scope._camera.left) / scope._camera.zoom / elementRect.z;
- var _pedestalY = deltaY * (scope._camera.top - scope._camera.bottom) / scope._camera.zoom / elementRect.w;
- scope.truck(_truckX, _pedestalY, true);
- }
- };
- var dollyInternal = function dollyInternal(delta, x, y) {
- var dollyScale = Math.pow(0.95, -delta * scope.dollySpeed);
- if (scope._camera.isPerspectiveCamera) {
- var distance = scope._sphericalEnd.radius * dollyScale - scope._sphericalEnd.radius;
- var prevRadius = scope._sphericalEnd.radius;
- scope.dolly(distance);
- if (scope.dollyToCursor) {
- scope._dollyControlAmount += scope._sphericalEnd.radius - prevRadius;
- scope._dollyControlCoord.set(x, y);
- }
- } else if (scope._camera.isOrthographicCamera) {
- scope._camera.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope._camera.zoom * dollyScale));
- scope._camera.updateProjectionMatrix();
- scope._hasUpdated = true;
- }
- };
- var scope = _assertThisInitialized(_this);
- var dragStart = new THREE.Vector2();
- var dollyStart = new THREE.Vector2();
- var elementRect;
- _this._domElement.addEventListener('mousedown', onMouseDown);
- _this._domElement.addEventListener('touchstart', onTouchStart);
- _this._domElement.addEventListener('wheel', onMouseWheel);
- _this._domElement.addEventListener('contextmenu', onContextMenu);
- _this._removeAllEventListeners = function () {
- scope._domElement.removeEventListener('mousedown', onMouseDown);
- scope._domElement.removeEventListener('touchstart', onTouchStart);
- scope._domElement.removeEventListener('wheel', onMouseWheel);
- scope._domElement.removeEventListener('contextmenu', onContextMenu);
- document.removeEventListener('mousemove', dragging);
- document.removeEventListener('touchmove', dragging);
- document.removeEventListener('mouseup', endDragging);
- document.removeEventListener('touchend', endDragging);
- };
- }
- return _this;
- } // wrong. phi should be map to polar, but backward compatibility.
- _createClass(CameraControls, [{
- key: "rotate",
- // azimuthAngle in radian
- // polarAngle in radian
- value: function rotate(azimuthAngle, polarAngle, enableTransition) {
- this.rotateTo(this._sphericalEnd.theta + azimuthAngle, this._sphericalEnd.phi + polarAngle, enableTransition);
- } // azimuthAngle in radian
- // polarAngle in radian
- }, {
- key: "rotateTo",
- value: function rotateTo(azimuthAngle, polarAngle, enableTransition) {
- var theta = Math.max(this.minAzimuthAngle, Math.min(this.maxAzimuthAngle, azimuthAngle));
- var phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, polarAngle));
- this._sphericalEnd.theta = theta;
- this._sphericalEnd.phi = phi;
- this._sphericalEnd.makeSafe();
- if (!enableTransition) {
- this._spherical.theta = this._sphericalEnd.theta;
- this._spherical.phi = this._sphericalEnd.phi;
- }
- this._hasUpdated = true;
- }
- }, {
- key: "dolly",
- value: function dolly(distance, enableTransition) {
- if (this._camera.isOrthographicCamera) {
- console.warn('dolly is not available for OrthographicCamera');
- return;
- }
- this.dollyTo(this._sphericalEnd.radius + distance, enableTransition);
- }
- }, {
- key: "dollyTo",
- value: function dollyTo(distance, enableTransition) {
- if (this._camera.isOrthographicCamera) {
- console.warn('dolly is not available for OrthographicCamera');
- return;
- }
- this._sphericalEnd.radius = THREE.Math.clamp(distance, this.minDistance, this.maxDistance);
- if (!enableTransition) {
- this._spherical.radius = this._sphericalEnd.radius;
- }
- this._hasUpdated = true;
- }
- }, {
- key: "pan",
- value: function pan(x, y, enableTransition) {
- console.log('`pan` has been renamed to `truck`');
- this.truck(x, y, enableTransition);
- }
- }, {
- key: "truck",
- value: function truck(x, y, enableTransition) {
- this._camera.updateMatrix();
- _xColumn.setFromMatrixColumn(this._camera.matrix, 0);
- _yColumn.setFromMatrixColumn(this._camera.matrix, 1);
- _xColumn.multiplyScalar(x);
- _yColumn.multiplyScalar(-y);
- var offset = _v3A.copy(_xColumn).add(_yColumn);
- this._encloseToBoundary(this._targetEnd, offset, this.boundaryFriction);
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "forward",
- value: function forward(distance, enableTransition) {
- _v3A.setFromMatrixColumn(this._camera.matrix, 0);
- _v3A.crossVectors(this._camera.up, _v3A);
- _v3A.multiplyScalar(distance);
- this._encloseToBoundary(this._targetEnd, _v3A, this.boundaryFriction);
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "moveTo",
- value: function moveTo(x, y, z, enableTransition) {
- this._targetEnd.set(x, y, z);
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "fitTo",
- value: function fitTo(box3OrObject, enableTransition) {
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- if (this._camera.isOrthographicCamera) {
- console.warn('fitTo is not supported for OrthographicCamera');
- return;
- }
- var paddingLeft = options.paddingLeft || 0;
- var paddingRight = options.paddingRight || 0;
- var paddingBottom = options.paddingBottom || 0;
- var paddingTop = options.paddingTop || 0;
- var boundingBox = box3OrObject.isBox3 ? box3OrObject.clone() : new THREE.Box3().setFromObject(box3OrObject);
- var size = boundingBox.getSize(_v3A);
- var boundingWidth = size.x + paddingLeft + paddingRight;
- var boundingHeight = size.y + paddingTop + paddingBottom;
- var boundingDepth = size.z;
- var distance = this.getDistanceToFit(boundingWidth, boundingHeight, boundingDepth);
- this.dollyTo(distance, enableTransition);
- var boundingBoxCenter = boundingBox.getCenter(_v3A);
- var cx = boundingBoxCenter.x - (paddingLeft * 0.5 - paddingRight * 0.5);
- var cy = boundingBoxCenter.y + (paddingTop * 0.5 - paddingBottom * 0.5);
- var cz = boundingBoxCenter.z;
- this.moveTo(cx, cy, cz, enableTransition);
- this._sanitizeSphericals();
- this.rotateTo(0, 90 * THREE.Math.DEG2RAD, enableTransition);
- }
- }, {
- key: "setLookAt",
- value: function setLookAt(positionX, positionY, positionZ, targetX, targetY, targetZ, enableTransition) {
- var position = _v3A.set(positionX, positionY, positionZ);
- var target = _v3B.set(targetX, targetY, targetZ);
- this._targetEnd.copy(target);
- this._sphericalEnd.setFromVector3(position.sub(target).applyQuaternion(this._yAxisUpSpace));
- this._sanitizeSphericals();
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- this._spherical.copy(this._sphericalEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "lerpLookAt",
- value: function lerpLookAt(positionAX, positionAY, positionAZ, targetAX, targetAY, targetAZ, positionBX, positionBY, positionBZ, targetBX, targetBY, targetBZ, t, enableTransition) {
- var positionA = _v3A.set(positionAX, positionAY, positionAZ);
- var targetA = _v3B.set(targetAX, targetAY, targetAZ);
- _sphericalA.setFromVector3(positionA.sub(targetA).applyQuaternion(this._yAxisUpSpace));
- var targetB = _v3A.set(targetBX, targetBY, targetBZ);
- this._targetEnd.copy(targetA).lerp(targetB, t); // tricky
- var positionB = _v3B.set(positionBX, positionBY, positionBZ);
- _sphericalB.setFromVector3(positionB.sub(targetB).applyQuaternion(this._yAxisUpSpace));
- var deltaTheta = _sphericalB.theta - _sphericalA.theta;
- var deltaPhi = _sphericalB.phi - _sphericalA.phi;
- var deltaRadius = _sphericalB.radius - _sphericalA.radius;
- this._sphericalEnd.set(_sphericalA.radius + deltaRadius * t, _sphericalA.phi + deltaPhi * t, _sphericalA.theta + deltaTheta * t);
- this._sanitizeSphericals();
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- this._spherical.copy(this._sphericalEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "setPosition",
- value: function setPosition(positionX, positionY, positionZ, enableTransition) {
- this.setLookAt(positionX, positionY, positionZ, this._targetEnd.x, this._targetEnd.y, this._targetEnd.z, enableTransition);
- }
- }, {
- key: "setTarget",
- value: function setTarget(targetX, targetY, targetZ, enableTransition) {
- var pos = this.getPosition(_v3A);
- this.setLookAt(pos.x, pos.y, pos.z, targetX, targetY, targetZ, enableTransition);
- }
- }, {
- key: "setBoundary",
- value: function setBoundary(box3) {
- if (!box3) {
- this._boundary.min.set(-Infinity, -Infinity, -Infinity);
- this._boundary.max.set(Infinity, Infinity, Infinity);
- this._hasUpdated = true;
- return;
- }
- this._boundary.copy(box3);
- this._boundary.clampPoint(this._targetEnd, this._targetEnd);
- this._hasUpdated = true;
- }
- }, {
- key: "setViewport",
- value: function setViewport(viewportOrX, y, width, height) {
- if (viewportOrX === null) {
- // null
- this._viewport = null;
- return;
- }
- this._viewport = this._viewport || new THREE.Vector4();
- if (typeof viewportOrX === 'number') {
- // number
- this._viewport.set(viewportOrX, y, width, height);
- } else {
- // Vector4
- this._viewport.copy(viewportOrX);
- }
- }
- }, {
- key: "getDistanceToFit",
- value: function getDistanceToFit(width, height, depth) {
- var camera = this._camera;
- var boundingRectAspect = width / height;
- var fov = camera.fov * THREE.Math.DEG2RAD;
- var aspect = camera.aspect;
- var heightToFit = boundingRectAspect < aspect ? height : width / aspect;
- return heightToFit * 0.5 / Math.tan(fov * 0.5) + depth * 0.5;
- }
- }, {
- key: "getTarget",
- value: function getTarget(out) {
- var _out = !!out && out.isVector3 ? out : new THREE.Vector3();
- return _out.copy(this._targetEnd);
- }
- }, {
- key: "getPosition",
- value: function getPosition(out) {
- var _out = !!out && out.isVector3 ? out : new THREE.Vector3();
- return _out.setFromSpherical(this._sphericalEnd).applyQuaternion(this._yAxisUpSpaceInverse).add(this._targetEnd);
- }
- }, {
- key: "reset",
- value: function reset(enableTransition) {
- this.setLookAt(this._position0.x, this._position0.y, this._position0.z, this._target0.x, this._target0.y, this._target0.z, enableTransition);
- }
- }, {
- key: "saveState",
- value: function saveState() {
- this._target0.copy(this._target);
- this._position0.copy(this._camera.position);
- this._zoom0 = this._camera.zoom;
- }
- }, {
- key: "updateCameraUp",
- value: function updateCameraUp() {
- this._yAxisUpSpace.setFromUnitVectors(this._camera.up, _AXIS_Y);
- this._yAxisUpSpaceInverse.copy(this._yAxisUpSpace).inverse();
- }
- }, {
- key: "update",
- value: function update(delta) {
- var currentDampingFactor = this._state === STATE.NONE ? this.dampingFactor : this.draggingDampingFactor;
- var lerpRatio = 1.0 - Math.exp(-currentDampingFactor * delta / 0.016);
- var deltaTheta = this._sphericalEnd.theta - this._spherical.theta;
- var deltaPhi = this._sphericalEnd.phi - this._spherical.phi;
- var deltaRadius = this._sphericalEnd.radius - this._spherical.radius;
- var deltaTarget = _v3A.subVectors(this._targetEnd, this._target);
- if (Math.abs(deltaTheta) > EPSILON || Math.abs(deltaPhi) > EPSILON || Math.abs(deltaRadius) > EPSILON || Math.abs(deltaTarget.x) > EPSILON || Math.abs(deltaTarget.y) > EPSILON || Math.abs(deltaTarget.z) > EPSILON) {
- this._spherical.set(this._spherical.radius + deltaRadius * lerpRatio, this._spherical.phi + deltaPhi * lerpRatio, this._spherical.theta + deltaTheta * lerpRatio);
- this._target.add(deltaTarget.multiplyScalar(lerpRatio));
- this._hasUpdated = true;
- } else {
- this._spherical.copy(this._sphericalEnd);
- this._target.copy(this._targetEnd);
- }
- if (this._dollyControlAmount !== 0) {
- if (this._camera.isPerspectiveCamera) {
- var direction = _v3A.copy(_v3A.setFromSpherical(this._sphericalEnd).applyQuaternion(this._yAxisUpSpaceInverse)).normalize().negate();
- var planeX = _v3B.copy(direction).cross(_v3C.copy(this._camera.up)).normalize();
- if (planeX.lengthSq() === 0) planeX.x = 1.0;
- var planeY = _v3C.crossVectors(planeX, direction);
- var worldToScreen = this._sphericalEnd.radius * Math.tan(this._camera.fov * THREE.Math.DEG2RAD * 0.5);
- var prevRadius = this._sphericalEnd.radius - this._dollyControlAmount;
- var _lerpRatio = (prevRadius - this._sphericalEnd.radius) / this._sphericalEnd.radius;
- var cursor = _v3A.copy(this._targetEnd).add(planeX.multiplyScalar(this._dollyControlCoord.x * worldToScreen * this._camera.aspect)).add(planeY.multiplyScalar(this._dollyControlCoord.y * worldToScreen));
- this._targetEnd.lerp(cursor, _lerpRatio);
- this._target.copy(this._targetEnd);
- }
- this._dollyControlAmount = 0;
- }
- this._spherical.makeSafe();
- this._camera.position.setFromSpherical(this._spherical).applyQuaternion(this._yAxisUpSpaceInverse).add(this._target);
- this._camera.lookAt(this._target);
- if (this._boundaryEnclosesCamera) {
- this._encloseToBoundary(this._camera.position.copy(this._target), _v3A.setFromSpherical(this._spherical).applyQuaternion(this._yAxisUpSpaceInverse), 1.0);
- }
- var updated = this._hasUpdated;
- this._hasUpdated = false;
- if (updated) this.dispatchEvent({
- type: 'update'
- });
- return updated;
- }
- }, {
- key: "toJSON",
- value: function toJSON() {
- return JSON.stringify({
- enabled: this.enabled,
- minDistance: this.minDistance,
- maxDistance: infinityToMaxNumber(this.maxDistance),
- minPolarAngle: this.minPolarAngle,
- maxPolarAngle: infinityToMaxNumber(this.maxPolarAngle),
- minAzimuthAngle: infinityToMaxNumber(this.minAzimuthAngle),
- maxAzimuthAngle: infinityToMaxNumber(this.maxAzimuthAngle),
- dampingFactor: this.dampingFactor,
- draggingDampingFactor: this.draggingDampingFactor,
- dollySpeed: this.dollySpeed,
- truckSpeed: this.truckSpeed,
- dollyToCursor: this.dollyToCursor,
- verticalDragToForward: this.verticalDragToForward,
- target: this._targetEnd.toArray(),
- position: this._camera.position.toArray(),
- target0: this._target0.toArray(),
- position0: this._position0.toArray()
- });
- }
- }, {
- key: "fromJSON",
- value: function fromJSON(json, enableTransition) {
- var obj = JSON.parse(json);
- var position = new THREE.Vector3().fromArray(obj.position);
- this.enabled = obj.enabled;
- this.minDistance = obj.minDistance;
- this.maxDistance = maxNumberToInfinity(obj.maxDistance);
- this.minPolarAngle = obj.minPolarAngle;
- this.maxPolarAngle = maxNumberToInfinity(obj.maxPolarAngle);
- this.minAzimuthAngle = maxNumberToInfinity(obj.minAzimuthAngle);
- this.maxAzimuthAngle = maxNumberToInfinity(obj.maxAzimuthAngle);
- this.dampingFactor = obj.dampingFactor;
- this.draggingDampingFactor = obj.draggingDampingFactor;
- this.dollySpeed = obj.dollySpeed;
- this.truckSpeed = obj.truckSpeed;
- this.dollyToCursor = obj.dollyToCursor;
- this.verticalDragToForward = obj.verticalDragToForward;
- this._target0.fromArray(obj.target0);
- this._position0.fromArray(obj.position0);
- this._targetEnd.fromArray(obj.target);
- this._sphericalEnd.setFromVector3(position.sub(this._target0).applyQuaternion(this._yAxisUpSpace));
- if (!enableTransition) {
- this._target.copy(this._targetEnd);
- this._spherical.copy(this._sphericalEnd);
- }
- this._hasUpdated = true;
- }
- }, {
- key: "dispose",
- value: function dispose() {
- this._removeAllEventListeners();
- }
- }, {
- key: "_encloseToBoundary",
- value: function _encloseToBoundary(position, offset, friction) {
- var offsetLength2 = offset.lengthSq();
- if (offsetLength2 === 0.0) {
- // sanity check
- return position;
- } // See: https://twitter.com/FMS_Cat/status/1106508958640988161
- var newTarget = _v3B.copy(offset).add(position); // target
- var clampedTarget = this._boundary.clampPoint(newTarget, _v3C); // clamped target
- var deltaClampedTarget = clampedTarget.sub(newTarget); // newTarget -> clampedTarget
- var deltaClampedTargetLength2 = deltaClampedTarget.lengthSq(); // squared length of deltaClampedTarget
- if (deltaClampedTargetLength2 === 0.0) {
- // when the position doesn't have to be clamped
- return position.add(offset);
- } else if (deltaClampedTargetLength2 === offsetLength2) {
- // when the position is completely stuck
- return position;
- } else if (friction === 0.0) {
- return position.add(offset).add(deltaClampedTarget);
- } else {
- var offsetFactor = 1.0 + friction * deltaClampedTargetLength2 / offset.dot(deltaClampedTarget);
- return position.add(_v3B.copy(offset).multiplyScalar(offsetFactor)).add(deltaClampedTarget.multiplyScalar(1.0 - friction));
- }
- }
- }, {
- key: "_sanitizeSphericals",
- value: function _sanitizeSphericals() {
- this._sphericalEnd.theta = this._sphericalEnd.theta % PI_2;
- this._spherical.theta += PI_2 * Math.round((this._sphericalEnd.theta - this._spherical.theta) / PI_2);
- }
- /**
- * Get its client rect and package into given `THREE.Vector4` .
- */
- }, {
- key: "_getClientRect",
- value: function _getClientRect(target) {
- var rect = this._domElement.getBoundingClientRect();
- target.x = rect.left;
- target.y = rect.top;
- if (this._viewport) {
- target.x += this._viewport.x;
- target.y += rect.height - this._viewport.w - this._viewport.y;
- target.z = this._viewport.z;
- target.w = this._viewport.w;
- } else {
- target.z = rect.width;
- target.w = rect.height;
- }
- return target;
- }
- }, {
- key: "phiSpeed",
- set: function set(speed) {
- console.warn('phiSpeed was renamed. use azimuthRotateSpeed instead');
- this.azimuthRotateSpeed = speed;
- } // wrong. theta should be map to azimuth, but backward compatibility.
- }, {
- key: "thetaSpeed",
- set: function set(speed) {
- console.warn('thetaSpeed was renamed. use polarRotateSpeed instead');
- this.polarRotateSpeed = speed;
- }
- }, {
- key: "boundaryEnclosesCamera",
- get: function get() {
- return this._boundaryEnclosesCamera;
- },
- set: function set(boundaryEnclosesCamera) {
- this._boundaryEnclosesCamera = boundaryEnclosesCamera;
- this._hasUpdated = true;
- }
- }]);
- return CameraControls;
- }(EventDispatcher);
- function isTouchEvent(event) {
- return 'TouchEvent' in window && event instanceof TouchEvent;
- }
- function infinityToMaxNumber(value) {
- if (isFinite(value)) return value;
- if (value < 0) return -Number.MAX_VALUE;
- return Number.MAX_VALUE;
- }
- function maxNumberToInfinity(value) {
- if (Math.abs(value) < Number.MAX_VALUE) return value;
- return value * Infinity;
- }
- return CameraControls;
- }));
|