From 4d23837338720daa112b604f3488cefc7ca7bf5b Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Sat, 10 Apr 2021 15:22:55 -0400 Subject: [PATCH] Big damping on pointer up. Demo has Box, removed knot and trackball at center checkbox. --- Readme.md | 15 +- SpinControls.js | 41 +++-- example_camera_spin.html | 11 -- example_camera_spin_pointer_pivot.html | 217 ------------------------- index.html | 67 +++----- 5 files changed, 44 insertions(+), 307 deletions(-) delete mode 100644 example_camera_spin_pointer_pivot.html diff --git a/Readme.md b/Readme.md index 452166f..f94c1a5 100644 --- a/Readme.md +++ b/Readme.md @@ -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 @@ -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(); @@ -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 @@ -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 diff --git a/SpinControls.js b/SpinControls.js index 02ca771..2e5fae6 100644 --- a/SpinControls.js +++ b/SpinControls.js @@ -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 = { @@ -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 }; @@ -57,7 +59,6 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) { _isPointerDown = false, - _EPS = 0.000001; var changeEvent = { type: 'change' }; @@ -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 ) ); @@ -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 @@ -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; @@ -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 ); @@ -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 diff --git a/example_camera_spin.html b/example_camera_spin.html index e7c3d6e..debefac 100644 --- a/example_camera_spin.html +++ b/example_camera_spin.html @@ -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 ); diff --git a/example_camera_spin_pointer_pivot.html b/example_camera_spin_pointer_pivot.html deleted file mode 100644 index a87343c..0000000 --- a/example_camera_spin_pointer_pivot.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - Camera Spin Pointer Pivot Example - SpinControls - - - - - - -
- Camera Spin Pointer Pivot
Orbit camera - Left click / 1 finger | Pan - Right click / 2 fingers | Dolly - Mouse wheel / pinch -
- - - - - - - - - \ No newline at end of file diff --git a/index.html b/index.html index f67add9..2242fd3 100644 --- a/index.html +++ b/index.html @@ -126,7 +126,7 @@

SpinControls

- Click spheres to rotate. Click colorful knot to rotate about intersection point. + Click spheres to rotate. Click box to rotate about intersection point.

Camera | Orbit: Left click / 1 finger | Pan: Right click / 2 fingers | Zoom: Mouse wheel / pinch

@@ -144,11 +144,6 @@

SpinControls

-

- -

@@ -160,7 +155,7 @@

SpinControls