diff --git a/CameraSpinControls.js b/CameraSpinControls.js index 93bb214..702d9ed 100644 --- a/CameraSpinControls.js +++ b/CameraSpinControls.js @@ -4,6 +4,7 @@ * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author erich666 / http://erichaines.com + * @author Paul Elliott / http://vizworkshop.com */ // Hack of OrbitControls.js to use SpinControls.js for rotation. @@ -150,8 +151,10 @@ CameraSpinControls = function ( camera, domElement ) { lastPosition.copy( scope.object.position ); lastQuaternion.copy( scope.object.quaternion ); zoomChanged = false; - - scope.spinControl.resetInputAfterCameraMovement(); // Don't let camera movement to ratchet mouse movement over sphere across frames + + // Don't let camera movement cause mouse to move over sphere across frames + // thus we avoid rotating when panning or dollying + scope.spinControl.resetInputAfterCameraMovement(); return true; @@ -824,9 +827,9 @@ CameraSpinControls = function ( camera, domElement ) { window.addEventListener( 'keydown', onKeyDown, false ); scope.spinControl = new SpinControls( this.targetObj, 1, camera, this.domElement ); - // FIXME Camera movement moves point on sphere bug. scope.spinControl.rotateSensitivity *= -1; // Negated it to pull camera around sphere as if sphere is fixed. - // scope.spinControl.rotateAlgorithm = scope.spinControl.POINTER_SPHERE_MAPPING.HOLROYD; // Only Holroyd works well for camera movement at the moment + scope.spinControl.rotateAlgorithm = scope.spinControl.POINTER_SPHERE_MAPPING.SHOEMAKE; // Only Holroyd works well for camera movement at the moment + //FIXME CameraSpinControls jumps when moving off/on sphere with Shoemake mapping scope.domElement.addEventListener( 'touchend', onTouchEnd, true ); scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); diff --git a/SpinControls.js b/SpinControls.js index 7fab03f..e28bf6d 100644 --- a/SpinControls.js +++ b/SpinControls.js @@ -246,49 +246,46 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) { objToPointer.subVectors(ndc, objToPointer); // Scale by object screen size. TODO simplify if Orthographic camera. - objEdgePos.setFromMatrixPosition(_this.object.matrixWorld); // objEdgePos is aspirational on this line + objEdgePos.setFromMatrixPosition(_this.object.matrixWorld); // objEdgePos is still aspirational on this line var offset = new THREE.Vector3().set(_this.trackballRadius, 0, 0); - // rotate to point at screen center. TODO Investigate + // TODO Investigate rotating offset to point towards screen center for consitant screen space size. // objPos.z = 0; // if(objPos.lengthSq() > 0) { // offset.applyAxisAngle(point.set(0, 0, -1), offset.angleTo(objPos)); // } offset.applyQuaternion(cameraRot.setFromRotationMatrix(_this.camera.matrixWorld)); objEdgePos.add(offset); - objEdgePos.project( _this.camera ); // position in ndc/screen + objEdgePos.project(_this.camera); // position in ndc/screen objEdgePos.z = 0; objPos.z = 0; var objRadiusNDC = objEdgePos.distanceTo(objPos); - objToPointer.x = objToPointer.x * (1 / objRadiusNDC); - objToPointer.y = objToPointer.y * (1 / objRadiusNDC); + objToPointer.x /= objRadiusNDC; + objToPointer.y /= objRadiusNDC; if(_this.camera.aspect) { // Perspective camera probably objToPointer.y /= _this.camera.aspect; } // Pointer mapping code below derived from https://mimosa-pudica.net/3d-rotation/ - if( _this.rotateAlgorithm == _this.POINTER_SPHERE_MAPPING.HOLROYD ) { + if( _this.rotateAlgorithm === _this.POINTER_SPHERE_MAPPING.HOLROYD ) { var t = objToPointer.lengthSq(); if (t < 0.5) { point.set(objToPointer.x, objToPointer.y, Math.sqrt(1.0 - t)); - } - else { + } else { point.set(objToPointer.x, objToPointer.y, 1.0 / (2.0 * Math.sqrt(t))); point.normalize(); } } - else if( _this.rotateAlgorithm == _this.POINTER_SPHERE_MAPPING.SHOEMAKE ) { - //FIXME CameraSpinControls jumps when moving off/on sphere with Shoemake mapping + else if( _this.rotateAlgorithm === _this.POINTER_SPHERE_MAPPING.SHOEMAKE ) { var t = objToPointer.lengthSq(); if (t < 1.0) { point.set(objToPointer.x, objToPointer.y, Math.sqrt(1.0 - t)); - } - else { + } else { objToPointer.normalize(); point.set(objToPointer.x, objToPointer.y, 0.0); } } - else if( _this.rotateAlgorithm == _this.POINTER_SPHERE_MAPPING.HOLROYD ) { + else if( _this.rotateAlgorithm === _this.POINTER_SPHERE_MAPPING.AZIMUTHAL ) { var t = (Math.PI / 2.0) * objToPointer.length(); var sined = t < Number.EPSILON ? 1.0 : Math.sin(t) / t; objToPointer.multiplyScalar((Math.PI / 2.0) * sined); @@ -391,7 +388,7 @@ var SpinControls = function ( object, trackBallRadius, camera, domElement ) { _angularVelocity.set( 0, 0, 0 ); _isPointerDown = true; _isTouchDown = true; - _this.applyVelocity(); //Todo Should not be needed here + _this.applyVelocity(); //TODO Should not be needed here } diff --git a/example_simple.html b/example_simple.html index 0405d3b..e98460c 100644 --- a/example_simple.html +++ b/example_simple.html @@ -76,6 +76,7 @@ scene.add( group ); spinControl = new SpinControls( group, radius, camera, renderer.domElement ); + //spinControl.rotateAlgorithm = spinControl.POINTER_SPHERE_MAPPING.SHOEMAKE // options window.addEventListener( 'resize', onWindowResize, false ); diff --git a/index.html b/index.html index 335257c..8dc50b6 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,11 @@ padding: 15px; z-index:100; box-sizing: border-box; - pointer-events: none; + pointer-events: none; + } + + #mapping { + pointer-events: auto; } @@ -30,20 +34,28 @@
Spin Controls Left click or touch spheres to spin them as if touching a trackball.
+Elsewhere: Orbit camera - Left click / 1 finger | Dolly - Right click / 2 fingers | Zoom - Mouse wheel / pinch
++ Pointer to trackball sphere mapping method: + +