Академический Документы
Профессиональный Документы
Культура Документы
// How far you can orbit vertically, upper and lower limits.
// Range is 0 to Math.PI radians.
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
// 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 };
////////////
// internals
var scope = this;
var EPS = 0.000001;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var panStart = new THREE.Vector2();
var panEnd = new THREE.Vector2();
var panDelta = new THREE.Vector2();
var dollyStart = new THREE.Vector2();
var dollyEnd = new THREE.Vector2();
var dollyDelta = new THREE.Vector2();
var
var
var
var
phiDelta = 0;
thetaDelta = 0;
scale = 1;
pan = new THREE.Vector3();
// orthographic
scope.panLeft( delta.x * (scope.object.right - scope.obj
ect.left) / element.clientWidth );
scope.panUp( delta.y * (scope.object.top - scope.object.
bottom) / element.clientHeight );
} else {
// camera neither orthographic or perspective - warn use
r
console.warn( 'WARNING: OrbitControls.js encountered an
unknown camera type - pan disabled.' );
}
};
this.dollyIn = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale /= dollyScale;
};
this.dollyOut = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale *= dollyScale;
};
this.update = function () {
var position = this.object.position;
var offset = position.clone().sub( this.target );
// 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 between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle
, phi ) );
// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
var radius = offset.length() * scale;
// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance,
radius ) );
// move target to panned location
this.target.add( pan );
offset.x = radius * Math.sin( phi ) * Math.sin( theta );
offset.y = radius * Math.cos( phi );
offset.z = radius * Math.sin( phi ) * Math.cos( theta );
position.copy( this.target ).add( offset );
this.object.lookAt( this.target );
thetaDelta = 0;
phiDelta = 0;
scale = 1;
pan.set(0,0,0);
if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
this.dispatchEvent( changeEvent );
lastPosition.copy( this.object.position );
}
};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
return Math.pow( 0.95, scope.zoomSpeed );
}
function onMouseDown( event ) {
if ( scope.enabled === false ) { return; }
event.preventDefault();
if ( event.button === 0 ) {
if ( scope.noRotate === true ) { return; }
state = STATE.ROTATE;
rotateStart.set( event.clientX, event.clientY );
} else if ( event.button === 1 ) {
if ( scope.noZoom === true ) { return; }
state = STATE.DOLLY;
dollyStart.set( event.clientX, event.clientY );
} else if ( event.button === 2 ) {
if ( scope.noPan === true ) { return; }
state = STATE.PAN;
panStart.set( event.clientX, event.clientY );
}
// Greggman fix: https://github.com/greggman/three.js/commit/fde
9f9917d6d8381f06bf22cdff766029d1761be
scope.domElement.addEventListener( 'mousemove', onMouseMove, fal
se );
scope.domElement.addEventListener( 'mouseup', onMouseUp, false )
;
}
function onMouseMove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
var element = scope.domElement === document ? scope.domElement.b
ody : scope.domElement;
if ( state === STATE.ROTATE ) {
if ( scope.noRotate === true ) return;
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// 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 g
o 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.cl
ientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
delta = event.wheelDelta;
} else if ( event.detail ) { // Firefox
delta = - event.detail;
}
if ( delta > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
}
function onKeyDown( event ) {
if ( scope.enabled === false ) { return; }
if ( scope.noKeys === true ) { return; }
if ( scope.noPan === true ) { return; }
// pan a pixel - I guess for precise positioning?
// Greggman fix: https://github.com/greggman/three.js/commit/fde
9f9917d6d8381f06bf22cdff766029d1761be
var needUpdate = false;
switch ( event.keyCode ) {
case scope.keys.UP:
scope.pan( new THREE.Vector2( 0, scope.keyPanSpe
ed ) );
needUpdate = true;
break;
case scope.keys.BOTTOM:
scope.pan( new THREE.Vector2( 0, -scope.keyPanSp
eed ) );
needUpdate = true;
break;
case scope.keys.LEFT:
scope.pan( new THREE.Vector2( scope.keyPanSpeed,
0 ) );
needUpdate = true;
break;
case scope.keys.RIGHT:
scope.pan( new THREE.Vector2( -scope.keyPanSpeed
, 0 ) );
needUpdate = true;
break;
}
// Greggman fix: https://github.com/greggman/three.js/commit/fde
9f9917d6d8381f06bf22cdff766029d1761be
if ( needUpdate ) {
scope.update();
}
}
function touchstart( event ) {
if ( scope.enabled === false ) { return; }
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) { return; }
state = STATE.TOUCH_ROTATE;
rotateStart.set( event.touches[ 0 ].pageX, event
.touches[ 0 ].pageY );
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) { return; }
state = STATE.TOUCH_DOLLY;
var dx = event.touches[ 0 ].pageX - event.touche
s[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touche
s[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) { return; }
state = STATE.TOUCH_PAN;
panStart.set( event.touches[ 0 ].pageX, event.to
uches[ 0 ].pageY );
break;
default:
state = STATE.NONE;
}
}
function touchmove( event ) {
if ( scope.enabled === false ) { return; }
event.preventDefault();
event.stopPropagation();
var element = scope.domElement === document ? scope.domElement.b
ody : scope.domElement;
switch ( event.touches.length ) {
default:
state = STATE.NONE;
}
}
function touchend( /* event */ ) {
if ( scope.enabled === false ) { return; }
state = STATE.NONE;
}
this.domElement.addEventListener(
ent.preventDefault(); }, false );
this.domElement.addEventListener(
this.domElement.addEventListener(
this.domElement.addEventListener(
); // firefox