Skip to content

Commit

Permalink
Big damping on pointer up.
Browse files Browse the repository at this point in the history
Demo has Box, removed knot and trackball at center checkbox.
  • Loading branch information
Paul Elliott authored and PaulHax committed Apr 11, 2021
1 parent 83516c5 commit 4d23837
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 307 deletions.
15 changes: 4 additions & 11 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Trackball style control for three.js Object3Ds and Cameras. Featuring pointer to

Like other trackball style controls, SpinControls does not limit rotation about a "up" axis. THREE.OrbitControls and other “turntable” style controls constrain rotation about the up axis, often +Y. Constraints are good. But when a model has no natural up direction, or you must view a scene from a “rolled” orientation, use a trackball style control.

Unlike other trackball implementations, SpinControls keeps the trackball point clicked on under the cursor with raycasting. Also, to support unlimited rotation until the cursor hits the edge of the screen, a relative rotation option kicks in when the cursor is off the trackball.
Unlike other trackball implementations, SpinControls keeps the trackball point clicked on under the cursor with raycasting. To support unlimited rotation until the cursor hits the edge of the screen, a relative rotation option kicks in when the cursor is off the trackball.


## Spin Object3D
Expand All @@ -48,14 +48,14 @@ var spinControl = new SpinControls( mesh, radius, camera, renderer.domElement );
## Spin Camera
```javascript
var camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, 500 );

var cameraSpinControl = new CameraSpinControls( camera, renderer.domElement );
var cameraSpinControl.distanceFromPivot = 500;

// Call every frame, like before renderer.render( scene, camera ) in function animate()
cameraSpinControl.update();

// Call when viewport HTML element resizes or moves, probably in
// Call onWindowResize when viewport HTML element resizes or moves, probably in
// window.addEventListener( 'resize', onWindowResize, false );
cameraSpinControl.onWindowResize();

Expand Down Expand Up @@ -83,13 +83,7 @@ For large rotations with one gesture, SpinControls continues to rotate when the

### Camera pivot at application defined point

Sometimes you'ed like the camera to rotate around a point of interest that is not in the center of the screen. The application can set the pivot point to say the intersection of the mouse/pointer with a 3D model. Also enables dolly/zoom towards pointer position. See example_camera_spin_pointer_pivot.html.
```
controls.isTargetOffCenter = true;
...
var intersects = raycaster.intersectObjects( raycastable );
controls.setTargetPosition(intersects[0].point);
```
Sometimes you'ed like the camera to rotate around a point of interest that is not in the center of the screen. The application can set the pivot point to say the intersection of the mouse/pointer with a 3D model. Also enables dolly/zoom towards pointer position. See index.html.

### Rotation of THREE.Object3D

Expand All @@ -101,7 +95,6 @@ Use SpinControls when you want:

* Direct touch feel for THREE.Objects or the camera.
* Rotation when pointer is beyond object or viewport.
* Tried the rest, need the best.


## Links that helped
Expand Down
41 changes: 20 additions & 21 deletions SpinControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {
this.enabled = true;

this.rotateSensitivity = 1.0; // Keep at 1 for direct touching feel
this.relativelySpinOffTrackball = true;
this.enableDamping = true;
this.relativelySpinOffTrackball = true; // Rotation continues relativly when pointer is beyond trackball
this.enableDamping = true; // True for movement with momentum after pointer release on control.update
this.dampingFactor = 5; // Increase for more friction
this.spinAxisConstraint; // Set to a THREE.Vector3 to limit spinning to an axis
this.spinAxisConstraint; // Set to a THREE.Vector3 to limit spinning to about an axis

// Raycast projects pointer line through camera frustum for accurate trackball control.
// Shoemake has direct touching feel of pointer on orthographically projected sphere but jumps at sphere edge.
// Holyroyd smooths between sphere and hyperbola to avoid jump at sphere edge.
// Azimuthal from Yasuhiro Fujii has unlimited rotation behond the sphere edge.
this.POINTER_SPHERE_MAPPING = { SHOEMAKE: 'shoemake', HOLROYD: 'holroyd', AZIMUTHAL: 'azimuthal', RAYCAST: 'raycast'};
this.POINTER_SPHERE_MAPPING = { SHOEMAKE: 'shoemake', HOLROYD: 'holroyd',
AZIMUTHAL: 'azimuthal', RAYCAST: 'raycast' };

// Base this on angle change around sphere edge?
this.offTrackBallVelocityGainMap = {
Expand All @@ -41,7 +42,8 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {

// Internals
this._pointerMapping = this.POINTER_SPHERE_MAPPING.RAYCAST;
this._offTrackBallVelocityGain = this.offTrackBallVelocityGainMap[this._pointerMapping]
this._offTrackBallVelocityGain = this.offTrackBallVelocityGainMap[this._pointerMapping];
this._pointerUpVelDamping = 2000;

this.screen = { left: 0, top: 0, width: 0, height: 0 };

Expand All @@ -57,7 +59,6 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {

_isPointerDown = false,


_EPS = 0.000001;

var changeEvent = { type: 'change' };
Expand Down Expand Up @@ -470,7 +471,7 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {
/ Math.atan( _this.trackballRadius / objectToCamera.length() ); // Ball field of view angle size
objToPointer.normalize();
var deltaRadius = deltaMouse.dot( objToPointer ) * ndcPerBall / deltaTime;
_angularVelocity.setLength( deltaRadius * this._offTrackBallVelocityGain ); // Just set it because we are touching trackball without sliding
_angularVelocity.setLength( deltaRadius * _this._offTrackBallVelocityGain ); // Just set it because we are touching trackball without sliding

// Find polar angle change
lastPointOnSphere.copy( getPointerInSphere( lastNdc ) );
Expand Down Expand Up @@ -499,8 +500,10 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {

// call like this: spinControl.setPointerToSphereMapping(spinControl.POINTER_SPHERE_MAPPING.SHOEMAKE)
this.setPointerToSphereMapping = function ( mappingTechnique ) {
this._pointerMapping = mappingTechnique;
this._offTrackBallVelocityGain = this.offTrackBallVelocityGainMap[this._pointerMapping]

_this._pointerMapping = mappingTechnique;
_this._offTrackBallVelocityGain = _this.offTrackBallVelocityGainMap[_this._pointerMapping];

}

// listeners
Expand All @@ -521,6 +524,14 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {
this.handlePointerUp = function ( event ) {

event.preventDefault();

if( !_this.hasPointerMovedThisFrame ) {

// To support subtle touches do big dampening, not just zeroing velocity
var deltaTime = ( event.timeStamp - _lastPointerEventTime ) / 1000.0;
_angularVelocity.multiplyScalar( 1 / ( _this._pointerUpVelDamping * Math.pow(deltaTime, 2) + _this.dampingFactor * deltaTime + 1) );

}

_isPointerDown = false;

Expand Down Expand Up @@ -555,10 +566,6 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {

if ( _this.enabled === false ) return;

if( !_this.hasPointerMovedThisFrame || !_this.enableDamping ) {
_angularVelocity.set( 0, 0, 0 );
}

document.removeEventListener( 'mousemove', onMouseMove );
document.removeEventListener( 'mouseup', onMouseUp );

Expand Down Expand Up @@ -606,14 +613,6 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) {

if( _this.enabled === false ) return;

if( !_this.hasPointerMovedThisFrame ) {

// To support subtle touches do big dampening, not zeroing it
var deltaTime = ( event.timeStamp - _lastPointerEventTime ) / 1000.0;
_angularVelocity.multiplyScalar( 1 / ( 10 * deltaTime * _this.dampingFactor + 1 ) )

}

_this.handlePointerUp( event );

// override handlePointerUp if finger still down
Expand Down
11 changes: 0 additions & 11 deletions example_camera_spin.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,6 @@

cameraSpinControl = new CameraSpinControls( camera, renderer.domElement );

// Uncomment for third person view of CameraSpinControls
// And comment out CameraSpinControls above
// camera.position.set( 500, 200, 500 );
// camera.lookAt( 0, 0, 0 );
// var camera2 = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
// scene.add( camera2 );
// const axesHelper = new THREE.AxesHelper( 50 );
// camera2.add( axesHelper );
// cameraSpinControl = new CameraSpinControls( camera2, renderer.domElement );
// cameraSpinControl.distanceFromPivot = 200;

var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 1, 1 );
scene.add( light );
Expand Down
217 changes: 0 additions & 217 deletions example_camera_spin_pointer_pivot.html

This file was deleted.

Loading

0 comments on commit 4d23837

Please sign in to comment.