From e01f5a1a75b2e079d1ccfb82009a0872bb235ebf Mon Sep 17 00:00:00 2001 From: lewibs Date: Wed, 7 Feb 2024 16:51:47 -0500 Subject: [PATCH 1/9] added rotation to DragControls --- docs/examples/en/controls/DragControls.html | 7 ++- examples/jsm/controls/DragControls.js | 53 +++++++++++++++++---- examples/misc_controls_drag.html | 7 ++- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/docs/examples/en/controls/DragControls.html b/docs/examples/en/controls/DragControls.html index 067a29a19b67b1..a8a2e3972b349d 100644 --- a/docs/examples/en/controls/DragControls.html +++ b/docs/examples/en/controls/DragControls.html @@ -111,6 +111,11 @@

[property:Boolean transformGroup]

If set to `true`, [name] does not transform individual objects but the entire group. Default is `false`.

+

[property:String mode]

+

+ The current transformation mode. Possible values are "translate", and "rotate". Default is `translate`. +

+

Methods

See the base [page:EventDispatcher] class for common methods.

@@ -146,4 +151,4 @@

Source

[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js examples/jsm/controls/DragControls.js]

- + \ No newline at end of file diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index f93f7745075561..0b4f03d743cddc 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -12,10 +12,17 @@ const _raycaster = new Raycaster(); const _pointer = new Vector2(); const _offset = new Vector3(); +const _diff = new Vector2(); +const _start = new Vector2(); +const _end = new Vector2(); const _intersection = new Vector3(); const _worldPosition = new Vector3(); const _inverseMatrix = new Matrix4(); +const _up = new Vector3(); +const _horizen = new Vector3(); +const _lookAt = new Vector3(); + class DragControls extends EventDispatcher { constructor( _objects, _camera, _domElement ) { @@ -28,6 +35,8 @@ class DragControls extends EventDispatcher { const _intersections = []; + this.mode = "translate"; + // const scope = this; @@ -75,17 +84,31 @@ class DragControls extends EventDispatcher { if ( scope.enabled === false ) return; updatePointer( event ); - + _end.copy(_pointer); + _diff.subVectors(_end, _start); + _start.copy(_end); + _raycaster.setFromCamera( _pointer, _camera ); - + if ( _selected ) { + + if (scope.mode === "translate") { + + if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { + + _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); + + } + + } else if (scope.mode === "rotate") { - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); - + _diff.multiplyScalar(2); //Just a random scalling factor since it rotated too slow + _selected.rotateOnWorldAxis(_up, _diff.x); + _selected.rotateOnWorldAxis(_horizen.normalize(), -_diff.y); + } + scope.dispatchEvent( { type: 'drag', object: _selected } ); return; @@ -161,9 +184,19 @@ 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") { + + _up.set(0,1,0).applyQuaternion(_camera.quaternion).normalize(); + _horizen.set(1,0,0).applyQuaternion(_camera.quaternion).normalize(); + _lookAt.set(0,0,-1).applyQuaternion(_camera.quaternion).normalize(); + + } + } _domElement.style.cursor = 'move'; @@ -218,4 +251,4 @@ class DragControls extends EventDispatcher { } -export { DragControls }; +export { DragControls }; \ No newline at end of file diff --git a/examples/misc_controls_drag.html b/examples/misc_controls_drag.html index 90578cf3436dcc..333d5727692a2c 100644 --- a/examples/misc_controls_drag.html +++ b/examples/misc_controls_drag.html @@ -20,6 +20,7 @@
three.js webgl - drag controls
Use "Shift+Click" to add/remove objects to/from a group.
+ Use "M" to toggle between rotate and translate modes.
Grouped objects can be transformed as a union.
@@ -141,6 +142,10 @@ function onKeyDown( event ) { enableSelection = ( event.keyCode === 16 ) ? true : false; + + if (event.keyCode === 77) { + controls.mode = (controls.mode === "translate") ? "rotate" : "translate"; + } } @@ -209,4 +214,4 @@ - + \ No newline at end of file From 7c4ea587d4840679dfe06dddd705df7608642cf1 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 10:51:28 +0100 Subject: [PATCH 2/9] Update misc_controls_drag.html Clean up. --- examples/misc_controls_drag.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/misc_controls_drag.html b/examples/misc_controls_drag.html index 333d5727692a2c..853afbcb578411 100644 --- a/examples/misc_controls_drag.html +++ b/examples/misc_controls_drag.html @@ -20,7 +20,7 @@
three.js webgl - drag controls
Use "Shift+Click" to add/remove objects to/from a group.
- Use "M" to toggle between rotate and translate modes.
+ Use "M" to toggle between rotate and translate mode.
Grouped objects can be transformed as a union.
@@ -143,8 +143,10 @@ enableSelection = ( event.keyCode === 16 ) ? true : false; - if (event.keyCode === 77) { - controls.mode = (controls.mode === "translate") ? "rotate" : "translate"; + if ( event.keyCode === 77 ) { + + controls.mode = ( controls.mode === 'translate' ) ? 'rotate' : 'translate'; + } } @@ -214,4 +216,4 @@ - \ No newline at end of file + From 9548278e213605056025b8e44c1b6c6103f8faf7 Mon Sep 17 00:00:00 2001 From: lewibs Date: Thu, 8 Feb 2024 09:31:48 -0500 Subject: [PATCH 3/9] updated code per code review see #27689 for details --- docs/examples/en/controls/DragControls.html | 5 +++++ examples/jsm/controls/DragControls.js | 13 +++++++------ examples/misc_controls_drag.html | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/examples/en/controls/DragControls.html b/docs/examples/en/controls/DragControls.html index a8a2e3972b349d..45bbd2b72cffbd 100644 --- a/docs/examples/en/controls/DragControls.html +++ b/docs/examples/en/controls/DragControls.html @@ -116,6 +116,11 @@

[property:String mode]

The current transformation mode. Possible values are "translate", and "rotate". Default is `translate`.

+

[property:String rotateSpeed]

+

+ The speed at which the object will rotate when dragged in "rotate" mode. The higher the number the faster the rotation. Default is 1. +

+

Methods

See the base [page:EventDispatcher] class for common methods.

diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index 0b4f03d743cddc..032adbf627f9e4 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -20,8 +20,7 @@ const _worldPosition = new Vector3(); const _inverseMatrix = new Matrix4(); const _up = new Vector3(); -const _horizen = new Vector3(); -const _lookAt = new Vector3(); +const _right = new Vector3(); class DragControls extends EventDispatcher { @@ -37,6 +36,8 @@ class DragControls extends EventDispatcher { this.mode = "translate"; + this.rotateSpeed = 1; + // const scope = this; @@ -102,9 +103,9 @@ class DragControls extends EventDispatcher { } else if (scope.mode === "rotate") { - _diff.multiplyScalar(2); //Just a random scalling factor since it rotated too slow + _diff.multiplyScalar(this.rotateSpeed); _selected.rotateOnWorldAxis(_up, _diff.x); - _selected.rotateOnWorldAxis(_horizen.normalize(), -_diff.y); + _selected.rotateOnWorldAxis(_right.normalize(), -_diff.y); } @@ -191,9 +192,9 @@ class DragControls extends EventDispatcher { } else if (scope.mode === "rotate") { + //Note: the controls only support the Y+ rotation _up.set(0,1,0).applyQuaternion(_camera.quaternion).normalize(); - _horizen.set(1,0,0).applyQuaternion(_camera.quaternion).normalize(); - _lookAt.set(0,0,-1).applyQuaternion(_camera.quaternion).normalize(); + _right.set(1,0,0).applyQuaternion(_camera.quaternion).normalize(); } diff --git a/examples/misc_controls_drag.html b/examples/misc_controls_drag.html index 333d5727692a2c..0b1cb96823fb68 100644 --- a/examples/misc_controls_drag.html +++ b/examples/misc_controls_drag.html @@ -114,6 +114,7 @@ container.appendChild( renderer.domElement ); controls = new DragControls( [ ... objects ], camera, renderer.domElement ); + controls.rotateSpeed = 2; controls.addEventListener( 'drag', render ); // From 49e09009d8ca12e48f3b4819a54aa6c9dd7938f9 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 17:44:16 +0100 Subject: [PATCH 4/9] Update DragControls.js Clean up. --- examples/jsm/controls/DragControls.js | 55 +++++++++++++-------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index 032adbf627f9e4..fed0f77da24df9 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -34,7 +34,7 @@ class DragControls extends EventDispatcher { const _intersections = []; - this.mode = "translate"; + this.mode = 'translate'; this.rotateSpeed = 1; @@ -85,30 +85,29 @@ class DragControls extends EventDispatcher { if ( scope.enabled === false ) return; updatePointer( event ); - _end.copy(_pointer); - _diff.subVectors(_end, _start); - _start.copy(_end); - + _end.copy( _pointer ); + _diff.subVectors( _end, _start ); + _start.copy( _end ); + _raycaster.setFromCamera( _pointer, _camera ); - + if ( _selected ) { - - if (scope.mode === "translate") { - + + if ( scope.mode === 'translate' ) { + if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - + _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); - + } - - } else if (scope.mode === "rotate") { - _diff.multiplyScalar(this.rotateSpeed); - _selected.rotateOnWorldAxis(_up, _diff.x); - _selected.rotateOnWorldAxis(_right.normalize(), -_diff.y); - - } + } else if ( scope.mode === 'rotate' ) { + _diff.multiplyScalar( scope.rotateSpeed ); + _selected.rotateOnWorldAxis( _up, _diff.x ); + _selected.rotateOnWorldAxis( _right.normalize(), - _diff.y ); + + } scope.dispatchEvent( { type: 'drag', object: _selected } ); @@ -185,19 +184,19 @@ class DragControls extends EventDispatcher { if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - if (scope.mode === "translate") { - + if ( scope.mode === 'translate' ) { + _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - - } else if (scope.mode === "rotate") { - + + } else if ( scope.mode === 'rotate' ) { + //Note: the controls only support the Y+ rotation - _up.set(0,1,0).applyQuaternion(_camera.quaternion).normalize(); - _right.set(1,0,0).applyQuaternion(_camera.quaternion).normalize(); - + _up.set( 0, 1, 0 ).applyQuaternion( _camera.quaternion ).normalize(); + _right.set( 1, 0, 0 ).applyQuaternion( _camera.quaternion ).normalize(); + } - + } _domElement.style.cursor = 'move'; @@ -252,4 +251,4 @@ class DragControls extends EventDispatcher { } -export { DragControls }; \ No newline at end of file +export { DragControls }; From 1f4defd54bd3e2e99c48e08846d725d7bf23cac9 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 17:45:03 +0100 Subject: [PATCH 5/9] Update DragControls.html Clean up. --- docs/examples/en/controls/DragControls.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/en/controls/DragControls.html b/docs/examples/en/controls/DragControls.html index 45bbd2b72cffbd..ef6351b03f829f 100644 --- a/docs/examples/en/controls/DragControls.html +++ b/docs/examples/en/controls/DragControls.html @@ -113,12 +113,12 @@

[property:Boolean transformGroup]

[property:String mode]

- The current transformation mode. Possible values are "translate", and "rotate". Default is `translate`. + The current transformation mode. Possible values are `translate`, and `rotate`. Default is `translate`.

[property:String rotateSpeed]

- The speed at which the object will rotate when dragged in "rotate" mode. The higher the number the faster the rotation. Default is 1. + The speed at which the object will rotate when dragged in `rotate` mode. The higher the number the faster the rotation. Default is `1`.

Methods

@@ -156,4 +156,4 @@

Source

[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js examples/jsm/controls/DragControls.js]

- \ No newline at end of file + From dfd0e778310d9772809943684ef96f3b36ab0afc Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 17:46:36 +0100 Subject: [PATCH 6/9] Update DragControls.html Fix type. --- docs/examples/en/controls/DragControls.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/en/controls/DragControls.html b/docs/examples/en/controls/DragControls.html index ef6351b03f829f..2970bc4dab2fcf 100644 --- a/docs/examples/en/controls/DragControls.html +++ b/docs/examples/en/controls/DragControls.html @@ -116,7 +116,7 @@

[property:String mode]

The current transformation mode. Possible values are `translate`, and `rotate`. Default is `translate`.

-

[property:String rotateSpeed]

+

[property:Float rotateSpeed]

The speed at which the object will rotate when dragged in `rotate` mode. The higher the number the faster the rotation. Default is `1`.

From 1e2b36ba74c34813f9c08cad38799bbcfdb207bb Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 17:47:36 +0100 Subject: [PATCH 7/9] Update DragControls.js --- examples/jsm/controls/DragControls.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index fed0f77da24df9..e5f77501509be2 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -191,7 +191,7 @@ class DragControls extends EventDispatcher { } else if ( scope.mode === 'rotate' ) { - //Note: the controls only support the Y+ rotation + // the controls only support the Y+ coordinate system _up.set( 0, 1, 0 ).applyQuaternion( _camera.quaternion ).normalize(); _right.set( 1, 0, 0 ).applyQuaternion( _camera.quaternion ).normalize(); From aeb95feebb74aebcd7c23dcad4010c56502d5a41 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Thu, 8 Feb 2024 17:48:12 +0100 Subject: [PATCH 8/9] Update DragControls.js --- examples/jsm/controls/DragControls.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index e5f77501509be2..c5e8db5cac047c 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -191,7 +191,7 @@ class DragControls extends EventDispatcher { } else if ( scope.mode === 'rotate' ) { - // the controls only support the Y+ coordinate system + // the controls only support Y+ up _up.set( 0, 1, 0 ).applyQuaternion( _camera.quaternion ).normalize(); _right.set( 1, 0, 0 ).applyQuaternion( _camera.quaternion ).normalize(); From 28c6204e92fa7dc346022134e279c945d174a9b4 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 9 Feb 2024 16:28:34 +0100 Subject: [PATCH 9/9] Update DragControls.js --- examples/jsm/controls/DragControls.js | 63 ++++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index c5e8db5cac047c..bd21ef1a97f164 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -13,8 +13,7 @@ const _raycaster = new Raycaster(); const _pointer = new Vector2(); const _offset = new Vector3(); const _diff = new Vector2(); -const _start = new Vector2(); -const _end = new Vector2(); +const _previousPointer = new Vector2(); const _intersection = new Vector3(); const _worldPosition = new Vector3(); const _inverseMatrix = new Matrix4(); @@ -85,9 +84,6 @@ class DragControls extends EventDispatcher { if ( scope.enabled === false ) return; updatePointer( event ); - _end.copy( _pointer ); - _diff.subVectors( _end, _start ); - _start.copy( _end ); _raycaster.setFromCamera( _pointer, _camera ); @@ -103,7 +99,7 @@ class DragControls extends EventDispatcher { } else if ( scope.mode === 'rotate' ) { - _diff.multiplyScalar( scope.rotateSpeed ); + _diff.subVectors( _pointer, _previousPointer ).multiplyScalar( scope.rotateSpeed ); _selected.rotateOnWorldAxis( _up, _diff.x ); _selected.rotateOnWorldAxis( _right.normalize(), - _diff.y ); @@ -111,51 +107,53 @@ class DragControls extends EventDispatcher { 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; + + } } @@ -163,6 +161,8 @@ class DragControls extends EventDispatcher { } + _previousPointer.copy( _pointer ); + } function onPointerDown( event ) { @@ -205,6 +205,7 @@ class DragControls extends EventDispatcher { } + _previousPointer.copy( _pointer ); }