Skip to content

Commit

Permalink
TransformControls: Derive from Controls. (#29146)
Browse files Browse the repository at this point in the history
* TransformControls: Derive from `Controls`.

* Docs: Clean up.

* TransformControls: Clean up.

* Docs: Clean up.

* Docs: Clean up.
  • Loading branch information
Mugen87 authored Sep 12, 2024
1 parent ee17dec commit aaf577d
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 110 deletions.
15 changes: 0 additions & 15 deletions docs/examples/en/controls/DragControls.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,6 @@ <h2>Methods</h2>

<p>See the base [page:Controls] class for common methods.</p>

<h3>[method:undefined connect] ()</h3>
<p>
Adds the event listeners of the controls.
</p>

<h3>[method:undefined disconnect] ()</h3>
<p>
Removes the event listeners of the controls.
</p>

<h3>[method:undefined dispose] ()</h3>
<p>
Should be called if the controls is no longer required.
</p>

<h2>Source</h2>

<p>
Expand Down
29 changes: 7 additions & 22 deletions docs/examples/en/controls/TransformControls.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<link type="text/css" rel="stylesheet" href="page.css" />
</head>
<body>
[page:Object3D] &rarr;
[page:Controls] &rarr;

<h1>[name]</h1>

Expand Down Expand Up @@ -41,7 +41,7 @@ <h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
[page:Camera camera]: The camera of the rendered scene.
</p>
<p>
[page:HTMLDOMElement domElement]: The HTML element used for event listeners.
[page:HTMLDOMElement domElement]: The HTML element used for event listeners. (optional)
</p>
<p>
Creates a new instance of [name].
Expand Down Expand Up @@ -73,7 +73,7 @@ <h3>objectChange</h3>

<h2>Properties</h2>

<p>See the base [page:Object3D] class for common properties.</p>
<p>See the base [page:Controls] class for common properties.</p>

<h3>[property:String axis]</h3>
<p>
Expand All @@ -85,32 +85,16 @@ <h3>[property:Camera camera]</h3>
The camera of the rendered scene.
</p>

<h3>[property:HTMLDOMElement domElement]</h3>
<p>
The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
not set up new event listeners.
</p>

<h3>[property:Boolean dragging]</h3>
<p>
Whether or not dragging is currently performed. Read-only property.
</p>

<h3>[property:Boolean enabled]</h3>
<p>
Whether or not the controls are enabled.
</p>

<h3>[property:String mode]</h3>
<p>
The current transformation mode. Possible values are "translate", "rotate" and "scale". Default is `translate`.
</p>

<h3>[property:Object3D object]</h3>
<p>
The 3D object being controlled.
</p>

<h3>[property:Number rotationSnap]</h3>
<p>
By default, 3D objects are continuously rotated. If you set this property to a numeric value (radians), you can define in which
Expand Down Expand Up @@ -150,7 +134,7 @@ <h3>[property:Number translationSnap]</h3>

<h2>Methods</h2>

<p>See the base [page:Object3D] class for common methods.</p>
<p>See the base [page:Controls] class for common methods.</p>

<h3>[method:TransformControls attach] ( [param:Object3D object] )</h3>
<p>
Expand All @@ -167,9 +151,10 @@ <h3>[method:TransformControls detach] ()</h3>
Removes the current 3D object from the controls and makes the helper UI invisible.
</p>

<h3>[method:undefined dispose] ()</h3>
<h3>[method:Object3D getGizmo] ()</h3>
<p>
Should be called if the controls is no longer required.
Returns the visual representation of the controls. Add the gizmo to your scene to visually transform the attached
3D object.
</p>

<h3>[method:Raycaster getRaycaster] ()</h3>
Expand Down
2 changes: 1 addition & 1 deletion editor/js/Viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function Viewport( editor ) {

} );

sceneHelpers.add( transformControls );
sceneHelpers.add( transformControls.getGizmo() );

//

Expand Down
159 changes: 97 additions & 62 deletions examples/jsm/controls/TransformControls.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
BoxGeometry,
BufferGeometry,
Controls,
CylinderGeometry,
DoubleSide,
Euler,
Expand Down Expand Up @@ -36,32 +37,22 @@ const _mouseDownEvent = { type: 'mouseDown', mode: null };
const _mouseUpEvent = { type: 'mouseUp', mode: null };
const _objectChangeEvent = { type: 'objectChange' };

class TransformControls extends Object3D {
class TransformControls extends Controls {

constructor( camera, domElement ) {
constructor( camera, domElement = null ) {

super();

if ( domElement === undefined ) {

console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' );
domElement = document;
super( undefined, domElement );

}
const root = new TransformControlsRoot( this );
this._root = root;

this.isTransformControls = true;
const gizmo = new TransformControlsGizmo();
this._gizmo = gizmo;
root.add( gizmo );

this.visible = false;
this.domElement = domElement;
this.domElement.style.touchAction = 'none'; // disable touch scroll

const _gizmo = new TransformControlsGizmo();
this._gizmo = _gizmo;
this.add( _gizmo );

const _plane = new TransformControlsPlane();
this._plane = _plane;
this.add( _plane );
const plane = new TransformControlsPlane();
this._plane = plane;
root.add( plane );

const scope = this;

Expand All @@ -83,8 +74,8 @@ class TransformControls extends Object3D {
if ( propValue !== value ) {

propValue = value;
_plane[ propName ] = value;
_gizmo[ propName ] = value;
plane[ propName ] = value;
gizmo[ propName ] = value;

scope.dispatchEvent( { type: propName + '-changed', value: value } );
scope.dispatchEvent( _changeEvent );
Expand All @@ -96,8 +87,8 @@ class TransformControls extends Object3D {
} );

scope[ propName ] = defaultValue;
_plane[ propName ] = defaultValue;
_gizmo[ propName ] = defaultValue;
plane[ propName ] = defaultValue;
gizmo[ propName ] = defaultValue;

}

Expand Down Expand Up @@ -172,50 +163,38 @@ class TransformControls extends Object3D {
this._onPointerMove = onPointerMove.bind( this );
this._onPointerUp = onPointerUp.bind( this );

this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
this.domElement.addEventListener( 'pointermove', this._onPointerHover );
this.domElement.addEventListener( 'pointerup', this._onPointerUp );

}

// updateMatrixWorld updates key transformation variables
updateMatrixWorld( force ) {

if ( this.object !== undefined ) {
if ( domElement !== null ) {

this.object.updateMatrixWorld();

if ( this.object.parent === null ) {

console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );

} else {
this.connect();

this.object.parent.matrixWorld.decompose( this._parentPosition, this._parentQuaternion, this._parentScale );
}

}
}

this.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );
connect() {

this._parentQuaternionInv.copy( this._parentQuaternion ).invert();
this._worldQuaternionInv.copy( this.worldQuaternion ).invert();
this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
this.domElement.addEventListener( 'pointermove', this._onPointerHover );
this.domElement.addEventListener( 'pointerup', this._onPointerUp );

}
this.domElement.style.touchAction = 'none'; // disable touch scroll

this.camera.updateMatrixWorld();
this.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );
}

if ( this.camera.isOrthographicCamera ) {
disconnect() {

this.camera.getWorldDirection( this.eye ).negate();
this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
this.domElement.removeEventListener( 'pointermove', this._onPointerHover );
this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
this.domElement.removeEventListener( 'pointerup', this._onPointerUp );

} else {
this.domElement.style.touchAction = 'auto';

this.eye.copy( this.cameraPosition ).sub( this.worldPosition ).normalize();
}

}
getGizmo() {

super.updateMatrixWorld( force );
return this._root;

}

Expand Down Expand Up @@ -555,10 +534,7 @@ class TransformControls extends Object3D {

dispose() {

this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
this.domElement.removeEventListener( 'pointermove', this._onPointerHover );
this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
this.disconnect();

this.traverse( function ( child ) {

Expand All @@ -573,7 +549,7 @@ class TransformControls extends Object3D {
attach( object ) {

this.object = object;
this.visible = true;
this._root.visible = true;

return this;

Expand All @@ -583,9 +559,10 @@ class TransformControls extends Object3D {
detach() {

this.object = undefined;
this.visible = false;
this.axis = null;

this._root.visible = false;

return this;

}
Expand Down Expand Up @@ -778,6 +755,64 @@ const _v1 = new Vector3();
const _v2 = new Vector3();
const _v3 = new Vector3();

class TransformControlsRoot extends Object3D {

constructor( controls ) {

super();

this.isTransformControlsRoot = true;

this.controls = controls;
this.visible = false;

}

// updateMatrixWorld updates key transformation variables
updateMatrixWorld( force ) {

const controls = this.controls;

if ( controls.object !== undefined ) {

controls.object.updateMatrixWorld();

if ( controls.object.parent === null ) {

console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );

} else {

controls.object.parent.matrixWorld.decompose( controls._parentPosition, controls._parentQuaternion, controls._parentScale );

}

controls.object.matrixWorld.decompose( controls.worldPosition, controls.worldQuaternion, controls._worldScale );

controls._parentQuaternionInv.copy( controls._parentQuaternion ).invert();
controls._worldQuaternionInv.copy( controls.worldQuaternion ).invert();

}

controls.camera.updateMatrixWorld();
controls.camera.matrixWorld.decompose( controls.cameraPosition, controls.cameraQuaternion, controls._cameraScale );

if ( controls.camera.isOrthographicCamera ) {

controls.camera.getWorldDirection( controls.eye ).negate();

} else {

controls.eye.copy( controls.cameraPosition ).sub( controls.worldPosition ).normalize();

}

super.updateMatrixWorld( force );

}

}

class TransformControlsGizmo extends Object3D {

constructor() {
Expand Down
5 changes: 3 additions & 2 deletions examples/misc_controls_transform.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@

control = new TransformControls( currentCamera, renderer.domElement );
control.addEventListener( 'change', render );

control.addEventListener( 'dragging-changed', function ( event ) {

orbit.enabled = ! event.value;
Expand All @@ -89,7 +88,9 @@
scene.add( mesh );

control.attach( mesh );
scene.add( control );

const gizmo = control.getGizmo();
scene.add( gizmo );

window.addEventListener( 'resize', onWindowResize );

Expand Down
2 changes: 1 addition & 1 deletion examples/webgl_animation_skinning_ik.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
transformControls.showX = false;
transformControls.space = 'world';
transformControls.attach( OOI.target_hand_l );
scene.add( transformControls );
scene.add( transformControls.getGizmo() );

// disable orbitControls while using transformControls
transformControls.addEventListener( 'mouseDown', () => orbitControls.enabled = false );
Expand Down
2 changes: 1 addition & 1 deletion examples/webgl_geometry_spline_editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
controls.enabled = ! event.value;

} );
scene.add( transformControl );
scene.add( transformControl.getGizmo() );

transformControl.addEventListener( 'objectChange', function () {

Expand Down
Loading

0 comments on commit aaf577d

Please sign in to comment.