|
@@ -3,7 +3,7 @@
|
|
|
*/
|
|
|
|
|
|
THREE.OrbitControls = function( object, domElement ) {
|
|
|
-
|
|
|
+
|
|
|
this.object = object;
|
|
|
this.domElement = ( domElement !== undefined ? domElement : document );
|
|
|
|
|
@@ -15,13 +15,15 @@ THREE.OrbitControls = function( object, domElement ) {
|
|
|
this.userZoomSpeed = 1.0;
|
|
|
|
|
|
this.userRotate = true;
|
|
|
- this.userRotateSpeed = 2.0;
|
|
|
+ this.userRotateSpeed = 1.0;
|
|
|
|
|
|
this.autoRotate = false;
|
|
|
- this.autoRotateSpeed = 3.0; // 20 seconds per round when fps is 60
|
|
|
+ this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
|
|
|
|
|
// internals
|
|
|
|
|
|
+ var self = this;
|
|
|
+
|
|
|
var EPS = 0.000001;
|
|
|
var PIXELS_PER_ROUND = 1800;
|
|
|
|
|
@@ -33,58 +35,127 @@ THREE.OrbitControls = function( object, domElement ) {
|
|
|
var thetaDelta = 0;
|
|
|
var scale = 1;
|
|
|
|
|
|
- this.update = function () {
|
|
|
+ this.rotateLeft = function ( angle ) {
|
|
|
|
|
|
- var position = this.object.position;
|
|
|
+ if ( angle === undefined ) {
|
|
|
|
|
|
- // angle from z-axis around y-axis
|
|
|
- var theta = Math.atan2( position.x, position.z );
|
|
|
+ angle = getAutoRotationAngle();
|
|
|
|
|
|
- // angle from y-axis
|
|
|
- var phi = Math.atan2(
|
|
|
- Math.sqrt( position.x * position.x + position.z * position.z ),
|
|
|
- position.y
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- if ( this.autoRotate ) {
|
|
|
+ thetaDelta -= angle;
|
|
|
|
|
|
- theta += 2 * Math.PI / 60 / 60 * this.autoRotateSpeed;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.rotateRight = function ( angle ) {
|
|
|
+
|
|
|
+ if ( angle === undefined ) {
|
|
|
+
|
|
|
+ angle = getAutoRotationAngle();
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( this.userRotate ) {
|
|
|
-
|
|
|
- theta += thetaDelta;
|
|
|
- phi += phiDelta;
|
|
|
+ thetaDelta += angle;
|
|
|
+
|
|
|
+ };
|
|
|
|
|
|
- // restrict phi to be betwee EPS and PI-EPS
|
|
|
- phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
|
|
|
+ this.rotateUp = function ( angle ) {
|
|
|
+
|
|
|
+ if ( angle === undefined ) {
|
|
|
|
|
|
- thetaDelta = 0;
|
|
|
- phiDelta = 0;
|
|
|
+ angle = getAutoRotationAngle();
|
|
|
|
|
|
}
|
|
|
|
|
|
- var radius = position.clone().subSelf( this.center ).length();
|
|
|
- var offset = new THREE.Vector3();
|
|
|
- offset.x = radius * Math.sin( phi ) * Math.sin( theta );
|
|
|
- offset.y = radius * Math.cos( phi );
|
|
|
- offset.z = radius * Math.sin( phi ) * Math.cos( theta );
|
|
|
+ phiDelta -= angle;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ this.rotateDown = function ( angle ) {
|
|
|
+
|
|
|
+ if ( angle === undefined ) {
|
|
|
|
|
|
- if ( this.userZoom ) {
|
|
|
+ angle = getAutoRotationAngle();
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- offset.multiplyScalar( scale );
|
|
|
- scale = 1;
|
|
|
+ phiDelta += angle;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ this.zoomIn = function ( zoomScale ) {
|
|
|
+
|
|
|
+ if ( zoomScale === undefined ) {
|
|
|
+
|
|
|
+ zoomScale = getZoomScale();
|
|
|
|
|
|
}
|
|
|
|
|
|
+ scale /= zoomScale;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ this.zoomOut = function ( zoomScale ) {
|
|
|
+
|
|
|
+ if ( zoomScale === undefined ) {
|
|
|
+
|
|
|
+ zoomScale = getZoomScale();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ scale *= zoomScale;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ this.update = function () {
|
|
|
+
|
|
|
+ var position = this.object.position;
|
|
|
+ var offset = position.clone().subSelf( this.center )
|
|
|
+
|
|
|
+ // angle from z-axis around y-axis
|
|
|
+ var theta = Math.atan2( offset.x, offset.z );
|
|
|
+ // angle from y-axis
|
|
|
+ var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
|
|
|
+
|
|
|
+ if ( this.autoRotate ) {
|
|
|
+
|
|
|
+ this.rotateLeft( getAutoRotationAngle() );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ theta += thetaDelta;
|
|
|
+ phi += phiDelta;
|
|
|
+
|
|
|
+ // restrict phi to be betwee EPS and PI-EPS
|
|
|
+ phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
|
|
|
+
|
|
|
+ var radius = offset.length();
|
|
|
+ offset.x = radius * Math.sin( phi ) * Math.sin( theta );
|
|
|
+ offset.y = radius * Math.cos( phi );
|
|
|
+ offset.z = radius * Math.sin( phi ) * Math.cos( theta );
|
|
|
+ offset.multiplyScalar( scale );
|
|
|
+
|
|
|
position.copy( this.center ).addSelf( offset );
|
|
|
|
|
|
this.object.lookAt( this.center );
|
|
|
|
|
|
+ thetaDelta = 0;
|
|
|
+ phiDelta = 0;
|
|
|
+ scale = 1;
|
|
|
};
|
|
|
|
|
|
- var self = this;
|
|
|
+
|
|
|
+ function getAutoRotationAngle() {
|
|
|
+
|
|
|
+ return 2 * Math.PI / 60 / 60 * self.autoRotateSpeed;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function getZoomScale() {
|
|
|
+
|
|
|
+ return Math.pow( 0.95, self.userZoomSpeed );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
function onMouseMove( event ) {
|
|
|
|
|
@@ -93,8 +164,8 @@ THREE.OrbitControls = function( object, domElement ) {
|
|
|
rotateEnd.set( event.clientX, event.clientY );
|
|
|
rotateDelta.sub( rotateEnd, rotateStart );
|
|
|
|
|
|
- thetaDelta = -2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * self.userRotateSpeed;
|
|
|
- phiDelta = -2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * self.userRotateSpeed;
|
|
|
+ self.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * self.userRotateSpeed );
|
|
|
+ self.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * self.userRotateSpeed );
|
|
|
|
|
|
rotateStart.copy( rotateEnd );
|
|
|
|
|
@@ -123,30 +194,20 @@ THREE.OrbitControls = function( object, domElement ) {
|
|
|
|
|
|
if ( event.wheelDelta > 0 ) {
|
|
|
|
|
|
- scale = Math.pow( 0.95, self.userZoomSpeed );
|
|
|
+ self.zoomOut();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- scale = 1.0 / Math.pow( 0.95, self.userZoomSpeed );
|
|
|
+ self.zoomIn();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- function onKeyDown( event ) {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function onKeyUp( event ) {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
|
|
this.domElement.addEventListener( 'mousemove', onMouseMove, false );
|
|
|
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
|
|
|
this.domElement.addEventListener( 'mouseup', onMouseUp, false );
|
|
|
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
|
|
|
- this.domElement.addEventListener( 'keydown', onKeyDown, false );
|
|
|
- this.domElement.addEventListener( 'keyup', onKeyUp, false );
|
|
|
|
|
|
};
|