|
@@ -12,10 +12,15 @@ const _raycaster = new Raycaster();
|
|
|
|
|
|
const _pointer = new Vector2();
|
|
|
const _offset = new Vector3();
|
|
|
+const _diff = new Vector2();
|
|
|
+const _previousPointer = new Vector2();
|
|
|
const _intersection = new Vector3();
|
|
|
const _worldPosition = new Vector3();
|
|
|
const _inverseMatrix = new Matrix4();
|
|
|
|
|
|
+const _up = new Vector3();
|
|
|
+const _right = new Vector3();
|
|
|
+
|
|
|
class DragControls extends EventDispatcher {
|
|
|
|
|
|
constructor( _objects, _camera, _domElement ) {
|
|
@@ -28,6 +33,10 @@ class DragControls extends EventDispatcher {
|
|
|
|
|
|
const _intersections = [];
|
|
|
|
|
|
+ this.mode = 'translate';
|
|
|
+
|
|
|
+ this.rotateSpeed = 1;
|
|
|
+
|
|
|
//
|
|
|
|
|
|
const scope = this;
|
|
@@ -80,59 +89,71 @@ class DragControls extends EventDispatcher {
|
|
|
|
|
|
if ( _selected ) {
|
|
|
|
|
|
- if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
|
|
+ if ( scope.mode === 'translate' ) {
|
|
|
+
|
|
|
+ if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
|
|
|
|
|
- _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
|
|
|
+ _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if ( scope.mode === 'rotate' ) {
|
|
|
+
|
|
|
+ _diff.subVectors( _pointer, _previousPointer ).multiplyScalar( scope.rotateSpeed );
|
|
|
+ _selected.rotateOnWorldAxis( _up, _diff.x );
|
|
|
+ _selected.rotateOnWorldAxis( _right.normalize(), - _diff.y );
|
|
|
|
|
|
}
|
|
|
|
|
|
scope.dispatchEvent( { type: 'drag', object: _selected } );
|
|
|
|
|
|
- return;
|
|
|
+ _previousPointer.copy( _pointer );
|
|
|
|
|
|
- }
|
|
|
+ } else {
|
|
|
|
|
|
- // hover support
|
|
|
+ // hover support
|
|
|
|
|
|
- if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
|
|
|
+ if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
|
|
|
|
|
|
- _intersections.length = 0;
|
|
|
+ _intersections.length = 0;
|
|
|
|
|
|
- _raycaster.setFromCamera( _pointer, _camera );
|
|
|
- _raycaster.intersectObjects( _objects, scope.recursive, _intersections );
|
|
|
+ _raycaster.setFromCamera( _pointer, _camera );
|
|
|
+ _raycaster.intersectObjects( _objects, scope.recursive, _intersections );
|
|
|
|
|
|
- if ( _intersections.length > 0 ) {
|
|
|
+ if ( _intersections.length > 0 ) {
|
|
|
|
|
|
- const object = _intersections[ 0 ].object;
|
|
|
+ const object = _intersections[ 0 ].object;
|
|
|
|
|
|
- _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
|
|
|
+ _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
|
|
|
|
|
|
- if ( _hovered !== object && _hovered !== null ) {
|
|
|
+ if ( _hovered !== object && _hovered !== null ) {
|
|
|
|
|
|
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
|
|
+ scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
|
|
|
|
|
- _domElement.style.cursor = 'auto';
|
|
|
- _hovered = null;
|
|
|
+ _domElement.style.cursor = 'auto';
|
|
|
+ _hovered = null;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if ( _hovered !== object ) {
|
|
|
+ if ( _hovered !== object ) {
|
|
|
|
|
|
- scope.dispatchEvent( { type: 'hoveron', object: object } );
|
|
|
+ scope.dispatchEvent( { type: 'hoveron', object: object } );
|
|
|
|
|
|
- _domElement.style.cursor = 'pointer';
|
|
|
- _hovered = object;
|
|
|
+ _domElement.style.cursor = 'pointer';
|
|
|
+ _hovered = object;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
|
|
|
- } else {
|
|
|
+ if ( _hovered !== null ) {
|
|
|
|
|
|
- if ( _hovered !== null ) {
|
|
|
+ scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
|
|
|
|
|
- scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
|
|
+ _domElement.style.cursor = 'auto';
|
|
|
+ _hovered = null;
|
|
|
|
|
|
- _domElement.style.cursor = 'auto';
|
|
|
- _hovered = null;
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -140,6 +161,8 @@ class DragControls extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ _previousPointer.copy( _pointer );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
function onPointerDown( event ) {
|
|
@@ -161,8 +184,18 @@ class DragControls extends EventDispatcher {
|
|
|
|
|
|
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
|
|
|
|
|
- _inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
|
|
|
- _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
|
|
|
+ if ( scope.mode === 'translate' ) {
|
|
|
+
|
|
|
+ _inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
|
|
|
+ _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
|
|
|
+
|
|
|
+ } else if ( scope.mode === 'rotate' ) {
|
|
|
+
|
|
|
+ // the controls only support Y+ up
|
|
|
+ _up.set( 0, 1, 0 ).applyQuaternion( _camera.quaternion ).normalize();
|
|
|
+ _right.set( 1, 0, 0 ).applyQuaternion( _camera.quaternion ).normalize();
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -172,6 +205,7 @@ class DragControls extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ _previousPointer.copy( _pointer );
|
|
|
|
|
|
}
|
|
|
|