From e5e34773785af82ae930f4fb216e85b1f74a45c9 Mon Sep 17 00:00:00 2001 From: WestLangley Date: Fri, 24 Jan 2014 21:49:05 -0500 Subject: [PATCH] OrbitControls: Improved memory management. Minor cleanup. --- examples/js/controls/OrbitControls.js | 76 +++++++++++++++++---------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index c0251fc8ce..ff2961e7bc 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -34,6 +34,7 @@ THREE.OrbitControls = function ( object, domElement ) { // "target" sets the location of focus, where the control orbits around // and where it pans with respect to. this.target = new THREE.Vector3(); + // center is old, deprecated; use "target" instead this.center = this.target; @@ -41,6 +42,7 @@ THREE.OrbitControls = function ( object, domElement ) { // backwards compatibility this.noZoom = false; this.zoomSpeed = 1.0; + // Limits to how far you can dolly in and out this.minDistance = 0; this.maxDistance = Infinity; @@ -64,6 +66,7 @@ THREE.OrbitControls = function ( object, domElement ) { // Set to true to disable use of the keys this.noKeys = false; + // The four arrow keys this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; @@ -81,6 +84,9 @@ THREE.OrbitControls = function ( object, domElement ) { var panStart = new THREE.Vector2(); var panEnd = new THREE.Vector2(); var panDelta = new THREE.Vector2(); + var panOffset = new THREE.Vector3(); + + var offset = new THREE.Vector3(); var dollyStart = new THREE.Vector2(); var dollyEnd = new THREE.Vector2(); @@ -94,13 +100,13 @@ THREE.OrbitControls = function ( object, domElement ) { var lastPosition = new THREE.Vector3(); var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; + var state = STATE.NONE; // events var changeEvent = { type: 'change' }; - this.rotateLeft = function ( angle ) { if ( angle === undefined ) { @@ -128,11 +134,11 @@ THREE.OrbitControls = function ( object, domElement ) { // pass in distance in world space to move left this.panLeft = function ( distance ) { - var panOffset = new THREE.Vector3(); var te = this.object.matrix.elements; + // get X column of matrix - panOffset.set( te[0], te[1], te[2] ); - panOffset.multiplyScalar(-distance); + panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] ); + panOffset.multiplyScalar( - distance ); pan.add( panOffset ); @@ -141,18 +147,19 @@ THREE.OrbitControls = function ( object, domElement ) { // pass in distance in world space to move up this.panUp = function ( distance ) { - var panOffset = new THREE.Vector3(); var te = this.object.matrix.elements; + // get Y column of matrix - panOffset.set( te[4], te[5], te[6] ); - panOffset.multiplyScalar(distance); + panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] ); + panOffset.multiplyScalar( distance ); pan.add( panOffset ); + }; - // main entry point; pass in Vector2 of change desired in pixel space, + // pass in x,y of change desired in pixel space, // right and down are positive - this.pan = function ( delta ) { + this.pan = function ( deltaX, deltaY ) { var element = scope.domElement === document ? scope.domElement.body : scope.domElement; @@ -164,20 +171,21 @@ THREE.OrbitControls = function ( object, domElement ) { var targetDistance = offset.length(); // half of the fov is center to top of screen - targetDistance *= Math.tan( (scope.object.fov/2) * Math.PI / 180.0 ); + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + // we actually don't use screenWidth, since perspective camera is fixed to screen height - scope.panLeft( 2 * delta.x * targetDistance / element.clientHeight ); - scope.panUp( 2 * delta.y * targetDistance / element.clientHeight ); + scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight ); + scope.panUp( 2 * deltaY * targetDistance / element.clientHeight ); } else if ( scope.object.top !== undefined ) { // orthographic - scope.panLeft( delta.x * (scope.object.right - scope.object.left) / element.clientWidth ); - scope.panUp( delta.y * (scope.object.top - scope.object.bottom) / element.clientHeight ); + scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth ); + scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight ); } else { - // camera neither orthographic or perspective - warn user + // camera neither orthographic or perspective console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); } @@ -211,7 +219,8 @@ THREE.OrbitControls = function ( object, domElement ) { this.update = function () { var position = this.object.position; - var offset = position.clone().sub( this.target ); + + offset.copy( position ).sub( this.target ); // angle from z-axis around y-axis @@ -255,7 +264,7 @@ THREE.OrbitControls = function ( object, domElement ) { thetaDelta = 0; phiDelta = 0; scale = 1; - pan.set(0,0,0); + pan.set( 0, 0, 0 ); if ( lastPosition.distanceTo( this.object.position ) > 0 ) { @@ -308,7 +317,6 @@ THREE.OrbitControls = function ( object, domElement ) { } - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be scope.domElement.addEventListener( 'mousemove', onMouseMove, false ); scope.domElement.addEventListener( 'mouseup', onMouseUp, false ); @@ -331,6 +339,7 @@ THREE.OrbitControls = function ( object, domElement ) { // rotating across whole screen goes 360 degrees around scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + // rotating up and down along whole screen attempts to go 360, but limited to 180 scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); @@ -362,13 +371,12 @@ THREE.OrbitControls = function ( object, domElement ) { panEnd.set( event.clientX, event.clientY ); panDelta.subVectors( panEnd, panStart ); - scope.pan( panDelta ); + scope.pan( panDelta.x, panDelta.y ); panStart.copy( panEnd ); } - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be scope.update(); } @@ -377,7 +385,6 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false ) return; - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be scope.domElement.removeEventListener( 'mousemove', onMouseMove, false ); scope.domElement.removeEventListener( 'mouseup', onMouseUp, false ); @@ -389,8 +396,6 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false || scope.noZoom === true ) return; - event.preventDefault(); - var delta = 0; if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9 @@ -424,26 +429,29 @@ THREE.OrbitControls = function ( object, domElement ) { switch ( event.keyCode ) { case scope.keys.UP: - scope.pan( new THREE.Vector2( 0, scope.keyPanSpeed ) ); + scope.pan( 0, scope.keyPanSpeed ); scope.update(); break; + case scope.keys.BOTTOM: - scope.pan( new THREE.Vector2( 0, -scope.keyPanSpeed ) ); + scope.pan( 0, - scope.keyPanSpeed ); scope.update(); break; + case scope.keys.LEFT: - scope.pan( new THREE.Vector2( scope.keyPanSpeed, 0 ) ); + scope.pan( scope.keyPanSpeed, 0 ); scope.update(); break; + case scope.keys.RIGHT: - scope.pan( new THREE.Vector2( -scope.keyPanSpeed, 0 ) ); + scope.pan( - scope.keyPanSpeed, 0 ); scope.update(); break; } } - + function touchstart( event ) { if ( scope.enabled === false ) return; @@ -451,6 +459,7 @@ THREE.OrbitControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: // one-fingered touch: rotate + if ( scope.noRotate === true ) return; state = STATE.TOUCH_ROTATE; @@ -459,6 +468,7 @@ THREE.OrbitControls = function ( object, domElement ) { break; case 2: // two-fingered touch: dolly + if ( scope.noZoom === true ) return; state = STATE.TOUCH_DOLLY; @@ -470,6 +480,7 @@ THREE.OrbitControls = function ( object, domElement ) { break; case 3: // three-fingered touch: pan + if ( scope.noPan === true ) return; state = STATE.TOUCH_PAN; @@ -478,9 +489,11 @@ THREE.OrbitControls = function ( object, domElement ) { break; default: + state = STATE.NONE; } + } function touchmove( event ) { @@ -495,6 +508,7 @@ THREE.OrbitControls = function ( object, domElement ) { switch ( event.touches.length ) { case 1: // one-fingered touch: rotate + if ( scope.noRotate === true ) return; if ( state !== STATE.TOUCH_ROTATE ) return; @@ -512,6 +526,7 @@ THREE.OrbitControls = function ( object, domElement ) { break; case 2: // two-fingered touch: dolly + if ( scope.noZoom === true ) return; if ( state !== STATE.TOUCH_DOLLY ) return; @@ -538,13 +553,14 @@ THREE.OrbitControls = function ( object, domElement ) { break; case 3: // three-fingered touch: pan + if ( scope.noPan === true ) return; if ( state !== STATE.TOUCH_PAN ) return; panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); panDelta.subVectors( panEnd, panStart ); - scope.pan( panDelta ); + scope.pan( panDelta.x, panDelta.y ); panStart.copy( panEnd ); @@ -552,6 +568,7 @@ THREE.OrbitControls = function ( object, domElement ) { break; default: + state = STATE.NONE; } @@ -563,6 +580,7 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false ) return; state = STATE.NONE; + } this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); -- GitLab