Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 95 additions & 26 deletions examples/js/controls/OrbitControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ THREE.OrbitControls = function ( object, domElement ) {
// "target" sets the location of focus, where the object orbits around
this.target = new THREE.Vector3();

// Set to true to enable trackball behavior
this.trackball = false;

// How far you can dolly in and out ( PerspectiveCamera only )
this.minDistance = 0;
this.maxDistance = Infinity;
Expand Down Expand Up @@ -68,6 +71,7 @@ THREE.OrbitControls = function ( object, domElement ) {

// Set to true to automatically rotate around the target
// If auto-rotate is enabled, you must call controls.update() in your animation loop
// auto-rotate is not supported for trackball behavior
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60

Expand All @@ -86,6 +90,7 @@ THREE.OrbitControls = function ( object, domElement ) {
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
this.quaternion0 = this.object.quaternion.clone();
this.zoom0 = this.object.zoom;

//
Expand All @@ -108,6 +113,7 @@ THREE.OrbitControls = function ( object, domElement ) {

scope.target0.copy( scope.target );
scope.position0.copy( scope.object.position );
scope.quaternion0.copy( scope.object.quaternion );
scope.zoom0 = scope.object.zoom;

};
Expand All @@ -116,6 +122,7 @@ THREE.OrbitControls = function ( object, domElement ) {

scope.target.copy( scope.target0 );
scope.object.position.copy( scope.position0 );
scope.object.quaternion.copy( scope.quaternion0 );
scope.object.zoom = scope.zoom0;

scope.object.updateProjectionMatrix();
Expand All @@ -139,49 +146,94 @@ THREE.OrbitControls = function ( object, domElement ) {
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();

var q = new THREE.Quaternion();
var vec = new THREE.Vector3();

return function update() {

var position = scope.object.position;

offset.copy( position ).sub( scope.target );

// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );
if ( scope.trackball ) {

// angle from z-axis around y-axis
spherical.setFromVector3( offset );
// rotate around screen-space y-axis

if ( scope.autoRotate && state === STATE.NONE ) {
if ( sphericalDelta.theta ) {

rotateLeft( getAutoRotationAngle() );
vec.set( 0, 1, 0 ).applyQuaternion( scope.object.quaternion );

}
var factor = ( scope.enableDamping ) ? scope.dampingFactor : 1;

q.setFromAxisAngle( vec, sphericalDelta.theta * factor );

scope.object.quaternion.premultiply( q );
offset.applyQuaternion( q );

}

// rotate around screen-space x-axis

if ( sphericalDelta.phi ) {

vec.set( 1, 0, 0 ).applyQuaternion( scope.object.quaternion );

var factor = ( scope.enableDamping ) ? scope.dampingFactor : 1;

if ( scope.enableDamping ) {
q.setFromAxisAngle( vec, sphericalDelta.phi * factor );

spherical.theta += sphericalDelta.theta * scope.dampingFactor;
spherical.phi += sphericalDelta.phi * scope.dampingFactor;
scope.object.quaternion.premultiply( q );
offset.applyQuaternion( q );

}

offset.multiplyScalar( scale );
offset.clampLength( scope.minDistance, scope.maxDistance );

} else {

spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );

}
if ( scope.autoRotate && state === STATE.NONE ) {

rotateLeft( getAutoRotationAngle() );

}

spherical.setFromVector3( offset );

if ( scope.enableDamping ) {

spherical.theta += sphericalDelta.theta * scope.dampingFactor;
spherical.phi += sphericalDelta.phi * scope.dampingFactor;

// restrict theta to be between desired limits
spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
} else {

// restrict phi to be between desired limits
spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;

spherical.makeSafe();
}

// restrict theta to be between desired limits
spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );

// restrict phi to be between desired limits
spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );

spherical.makeSafe();

spherical.radius *= scale;
spherical.radius *= scale;

// restrict radius to be between desired limits
spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
// restrict radius to be between desired limits
spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );

offset.setFromSpherical( spherical );

// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion( quatInverse );

}

// move target to panned location

Expand All @@ -195,14 +247,13 @@ THREE.OrbitControls = function ( object, domElement ) {

}

offset.setFromSpherical( spherical );
position.copy( scope.target ).add( offset );

// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion( quatInverse );
if ( scope.trackball === false ) {

position.copy( scope.target ).add( offset );
scope.object.lookAt( scope.target );

scope.object.lookAt( scope.target );
}

if ( scope.enableDamping === true ) {

Expand Down Expand Up @@ -1148,7 +1199,9 @@ THREE.OrbitControls = function ( object, domElement ) {

// force an update at start

this.object.lookAt( scope.target );
this.update();
this.saveState();

};

Expand Down Expand Up @@ -1178,3 +1231,19 @@ THREE.MapControls = function ( object, domElement ) {

THREE.MapControls.prototype = Object.create( THREE.EventDispatcher.prototype );
THREE.MapControls.prototype.constructor = THREE.MapControls;

//

THREE.TrackballControls = function ( object, domElement ) {

THREE.OrbitControls.call( this, object, domElement );

this.trackball = true;
this.screenSpacePanning = true;
this.autoRotate = false;

};

THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
THREE.TrackballControls.prototype.constructor = THREE.TrackballControls;

Loading