|
@@ -1,5 +1,6 @@
|
|
|
/**
|
|
|
* @author Eberhard Graether / http://egraether.com/
|
|
|
+ * @author Mark Lundin / http://mark-lundin.com
|
|
|
*/
|
|
|
|
|
|
THREE.TrackballControls = function ( object, domElement ) {
|
|
@@ -98,89 +99,102 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
- this.getMouseOnScreen = function ( clientX, clientY ) {
|
|
|
+ this.getMouseOnScreen = function ( clientX, clientY, optionalTarget ) {
|
|
|
|
|
|
- return new THREE.Vector2(
|
|
|
+ return ( optionalTarget || new THREE.Vector2() ).set(
|
|
|
( clientX - _this.screen.left ) / _this.screen.width,
|
|
|
( clientY - _this.screen.top ) / _this.screen.height
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
- this.getMouseProjectionOnBall = function ( clientX, clientY ) {
|
|
|
+ this.getMouseProjectionOnBall = (function(){
|
|
|
|
|
|
- var mouseOnBall = new THREE.Vector3(
|
|
|
- ( clientX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
|
|
|
- ( _this.screen.height * 0.5 + _this.screen.top - clientY ) / (_this.screen.height*.5),
|
|
|
- 0.0
|
|
|
- );
|
|
|
|
|
|
- var length = mouseOnBall.length();
|
|
|
+ var objectUp = new THREE.Vector3();
|
|
|
|
|
|
- if ( _this.noRoll ) {
|
|
|
|
|
|
- if ( length < Math.SQRT1_2 ) {
|
|
|
+ return function ( clientX, clientY, projection ) {
|
|
|
|
|
|
- mouseOnBall.z = Math.sqrt( 1.0 - length*length );
|
|
|
+ var mouseOnBall = new THREE.Vector3(
|
|
|
+ ( clientX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
|
|
|
+ ( _this.screen.height * 0.5 + _this.screen.top - clientY ) / (_this.screen.height*.5),
|
|
|
+ 0.0
|
|
|
+ );
|
|
|
|
|
|
- } else {
|
|
|
+ var length = mouseOnBall.length();
|
|
|
|
|
|
- mouseOnBall.z = .5 / length;
|
|
|
-
|
|
|
- }
|
|
|
+ if ( _this.noRoll ) {
|
|
|
|
|
|
- } else if ( length > 1.0 ) {
|
|
|
+ if ( length < Math.SQRT1_2 ) {
|
|
|
|
|
|
- mouseOnBall.normalize();
|
|
|
+ mouseOnBall.z = Math.sqrt( 1.0 - length*length );
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
+
|
|
|
+ mouseOnBall.z = .5 / length;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if ( length > 1.0 ) {
|
|
|
|
|
|
- mouseOnBall.z = Math.sqrt( 1.0 - length * length );
|
|
|
+ mouseOnBall.normalize();
|
|
|
|
|
|
+ } else {
|
|
|
+
|
|
|
+ mouseOnBall.z = Math.sqrt( 1.0 - length * length );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ _eye.copy( _this.object.position ).sub( _this.target );
|
|
|
+
|
|
|
+ projection.copy( _this.object.up ).setLength( mouseOnBall.y )
|
|
|
+ projection.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
|
|
|
+ projection.add( _eye.setLength( mouseOnBall.z ) );
|
|
|
+
|
|
|
+ return projection;
|
|
|
}
|
|
|
|
|
|
- _eye.copy( _this.object.position ).sub( _this.target );
|
|
|
+ }());
|
|
|
|
|
|
- var projection = _this.object.up.clone().setLength( mouseOnBall.y );
|
|
|
- projection.add( _this.object.up.clone().cross( _eye ).setLength( mouseOnBall.x ) );
|
|
|
- projection.add( _eye.setLength( mouseOnBall.z ) );
|
|
|
+ this.rotateCamera = (function(){
|
|
|
|
|
|
- return projection;
|
|
|
+ var axis = new THREE.Vector3(),
|
|
|
+ quaternion = new THREE.Quaternion();
|
|
|
|
|
|
- };
|
|
|
|
|
|
- this.rotateCamera = function () {
|
|
|
+ return function () {
|
|
|
|
|
|
- var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
|
|
|
+ var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
|
|
|
|
|
|
- if ( angle ) {
|
|
|
+ if ( angle ) {
|
|
|
|
|
|
- var axis = ( new THREE.Vector3() ).crossVectors( _rotateStart, _rotateEnd ).normalize(),
|
|
|
- quaternion = new THREE.Quaternion();
|
|
|
+ axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
|
|
|
|
|
|
- angle *= _this.rotateSpeed;
|
|
|
+ angle *= _this.rotateSpeed;
|
|
|
|
|
|
- quaternion.setFromAxisAngle( axis, -angle );
|
|
|
+ quaternion.setFromAxisAngle( axis, -angle );
|
|
|
|
|
|
- _eye.applyQuaternion( quaternion );
|
|
|
- _this.object.up.applyQuaternion( quaternion );
|
|
|
+ _eye.applyQuaternion( quaternion );
|
|
|
+ _this.object.up.applyQuaternion( quaternion );
|
|
|
|
|
|
- _rotateEnd.applyQuaternion( quaternion );
|
|
|
+ _rotateEnd.applyQuaternion( quaternion );
|
|
|
|
|
|
- if ( _this.staticMoving ) {
|
|
|
+ if ( _this.staticMoving ) {
|
|
|
|
|
|
- _rotateStart.copy( _rotateEnd );
|
|
|
+ _rotateStart.copy( _rotateEnd );
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
|
|
|
- quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
|
|
|
- _rotateStart.applyQuaternion( quaternion );
|
|
|
+ quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
|
|
|
+ _rotateStart.applyQuaternion( quaternion );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- };
|
|
|
+ }());
|
|
|
|
|
|
this.zoomCamera = function () {
|
|
|
|
|
@@ -214,33 +228,40 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
- this.panCamera = function () {
|
|
|
+ this.panCamera = (function(){
|
|
|
|
|
|
- var mouseChange = _panEnd.clone().sub( _panStart );
|
|
|
+ var mouseChange = new THREE.Vector2(),
|
|
|
+ objectUp = new THREE.Vector3(),
|
|
|
+ pan = new THREE.Vector3();
|
|
|
|
|
|
- if ( mouseChange.lengthSq() ) {
|
|
|
+ return function () {
|
|
|
|
|
|
- mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
|
|
|
+ mouseChange.copy( _panEnd ).sub( _panStart );
|
|
|
|
|
|
- var pan = _eye.clone().cross( _this.object.up ).setLength( mouseChange.x );
|
|
|
- pan.add( _this.object.up.clone().setLength( mouseChange.y ) );
|
|
|
+ if ( mouseChange.lengthSq() ) {
|
|
|
|
|
|
- _this.object.position.add( pan );
|
|
|
- _this.target.add( pan );
|
|
|
+ mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
|
|
|
|
|
|
- if ( _this.staticMoving ) {
|
|
|
+ pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
|
|
|
+ pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
|
|
|
|
|
|
- _panStart = _panEnd;
|
|
|
+ _this.object.position.add( pan );
|
|
|
+ _this.target.add( pan );
|
|
|
|
|
|
- } else {
|
|
|
+ if ( _this.staticMoving ) {
|
|
|
|
|
|
- _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
|
|
|
+ _panStart.copy( _panEnd );
|
|
|
|
|
|
- }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
|
|
|
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- };
|
|
|
+ }());
|
|
|
|
|
|
this.checkDistances = function () {
|
|
|
|
|
@@ -374,17 +395,17 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
if ( _state === STATE.ROTATE && !_this.noRotate ) {
|
|
|
|
|
|
- _rotateStart = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
|
|
|
+ _rotateStart = _this.getMouseProjectionOnBall( event.clientX, event.clientY, _rotateStart );
|
|
|
_rotateEnd.copy(_rotateStart)
|
|
|
|
|
|
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
|
|
|
|
|
|
- _zoomStart = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
+ _zoomStart = _this.getMouseOnScreen( event.clientX, event.clientY, _zoomStart );
|
|
|
_zoomEnd.copy(_zoomStart);
|
|
|
|
|
|
} else if ( _state === STATE.PAN && !_this.noPan ) {
|
|
|
|
|
|
- _panStart = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
+ _panStart = _this.getMouseOnScreen( event.clientX, event.clientY, _panStart);
|
|
|
_panEnd.copy(_panStart)
|
|
|
|
|
|
}
|
|
@@ -405,15 +426,15 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
if ( _state === STATE.ROTATE && !_this.noRotate ) {
|
|
|
|
|
|
- _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
|
|
|
+ _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY, _rotateEnd );
|
|
|
|
|
|
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
|
|
|
|
|
|
- _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
+ _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY, _zoomEnd );
|
|
|
|
|
|
} else if ( _state === STATE.PAN && !_this.noPan ) {
|
|
|
|
|
|
- _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
|
|
|
+ _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY, _panEnd );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -467,7 +488,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
case 1:
|
|
|
_state = STATE.TOUCH_ROTATE;
|
|
|
- _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _rotateEnd.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateStart ));
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
@@ -479,7 +500,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
|
|
|
case 3:
|
|
|
_state = STATE.TOUCH_PAN;
|
|
|
- _panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _panEnd.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panStart ));
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -501,7 +522,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
switch ( event.touches.length ) {
|
|
|
|
|
|
case 1:
|
|
|
- _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd );
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
@@ -511,7 +532,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
- _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd );
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -528,7 +549,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
switch ( event.touches.length ) {
|
|
|
|
|
|
case 1:
|
|
|
- _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _rotateStart.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd ));
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
@@ -536,7 +557,7 @@ THREE.TrackballControls = function ( object, domElement ) {
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
- _panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
|
|
+ _panStart.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd ));
|
|
|
break;
|
|
|
|
|
|
}
|