moussa
March 12, 2021, 8:29am
1
Hello Everyone,
Is there any way to disable orbitcontrols manual rotation on a specific object?
In other words, I want the orbitcontrols to be applied on a specific mesh and not on the scene camera.
Thank you
That is not what OrbitControls
is intended for. Seems you need something like this:
opened 06:34AM - 05 Mar 20 UTC
closed 04:08PM - 14 Mar 21 UTC
Enhancement
##### Feature request
OrbitControls were originally created to rotate a camer… a around a point in a scene:
<img width="400" alt="Screen Shot 2020-01-28 at 3 32 16 PM" src="https://user-images.githubusercontent.com/1710493/73314867-6cfb1f80-41e3-11ea-9e44-597ca914f2ba.png">
https://threejs.org/examples/#misc_controls_orbit
TransformControls were originally created for rotating individual objects within a scene:
<img width="400" alt="Screen Shot 2020-01-28 at 3 32 26 PM" src="https://user-images.githubusercontent.com/1710493/73314876-74222d80-41e3-11ea-93e0-fa89beb1b987.png">
https://threejs.org/examples/#misc_controls_transform
However in most examples and in web apps, we seem to be using OrbitControls to rotate objects? e.g.
https://threejs.org/examples/#webgl_materials_normalmap_object_space
https://threejs.org/examples/#webgl_clipping_intersection
https://threejs.org/examples/#webgl_clipping_stencil
https://threejs.org/examples/#webgl_decals
etc...
This usage creates confusion when you actually do want to rotate an object (and control the camera separately). In my case I needed the user to spin a globe, while the camera pans to a certain viewing angle.
Neither OrbitControls or TransformControls fully support the actual needed functionality needed for object spinning:
- OrbitControls locks your camera.lookAt to controls.target, and is spinning the camera not the object, which also spins the scenes.
- TransformControls correctly spins the object, but doesn't support damping / free spinning / hiding the gizmo gui.
So with that in mind, could we add an example for ObjectControls?
The controls implementation of Autodesk Forge viewer is probably a good benchmark:
https://forge-rcdb.autodesk.io/configurator?id=5904729b0007f5ead5b1196d
Some ideal features:
- Selecting an object
- Rotate object
- Lock axis
- Free spin in any direction
- Damping to slowly spin to a stop
Here is my attempt at a potential solution by using TransformControls as a reference:
index.html
```
control = new ObjectControls(camera, renderer.domElement);
control.enableDamping = true;
control.freeMode = true;
control.setMode('rotate');
control.showX = false;
control.showY = false;
control.showZ = false;
```
ObjectControls.js line 69
```
// Set to true to enable damping (inertia)
// If damping is enabled, you must call controls.update() in your animation loop
defineProperty( "enableDamping", false );
defineProperty( "dampingFactor", 0.05 );
defineProperty( "freeMode", false );
defineProperty( "rotateSpeed", 1.0 );
```
line 128:
```
var rotateStart = new Vector2();
var rotateEnd = new Vector2();
var rotateDelta = new Vector2();
```
line 255:
```
this.pointerHover = function ( pointer ) {
if ( this.object === undefined || this.dragging === true || ( pointer.button !== undefined && pointer.button !== 0 ) ) return;
if (this.freeMode === true) {
this.axis = 'XYZE';
return;
}
ray.setFromCamera( pointer, this.camera );
var intersect = ray.intersectObjects( _gizmo.picker[ this.mode ].children, true )[ 0 ] || false;
if ( intersect ) {
this.axis = intersect.object.name;
} else {
this.axis = null;
}
};
```
line 523:
`var ROTATION_SPEED = 2 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );`
line 724:
```
this.update = function () {
if (this.dragging === false && scope.enableDamping && (Math.abs(rotateDelta.x) > 0.01 || Math.abs(rotateDelta.y) > 0.01)) {
quaternionStart.copy( this.object.quaternion );
offset = new Vector3(
rotateDelta.x * 5,
- rotateDelta.y * 5,
0
);
rotateDelta.x *= 1 - scope.dampingFactor;
rotateDelta.y *= 1 - scope.dampingFactor;
var ROTATION_SPEED = .1 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
rotationAxis.copy( offset ).cross( eye ).normalize();
rotationAngle = offset.dot( _tempVector.copy( rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
rotationAxis.applyQuaternion( parentQuaternionInv );
this.object.quaternion.copy( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) );
this.object.quaternion.multiply( quaternionStart ).normalize();
}
};
```
line 644:
```
function onPointerDown( event ) {
if ( ! scope.enabled ) return;
rotateStart.set( event.clientX, event.clientY );
document.addEventListener( "mousemove", onPointerMove, false );
scope.pointerHover( getPointer( event ) );
scope.pointerDown( getPointer( event ) );
}
function onPointerMove( event ) {
if ( ! scope.enabled ) return;
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
scope.pointerMove( getPointer( event ) );
rotateStart.copy( rotateEnd );
}
```
line 1178:
```
if (this.freeMode === true) {
this.gizmo[ "translate" ].visible = false;
this.gizmo[ "rotate" ].visible = false;
this.gizmo[ "scale" ].visible = false;
this.helper[ "translate" ].visible = false;
this.helper[ "rotate" ].visible = false;
this.helper[ "scale" ].visible = false;
} else {
this.gizmo[ "translate" ].visible = this.mode === "translate";
this.gizmo[ "rotate" ].visible = this.mode === "rotate";
this.gizmo[ "scale" ].visible = this.mode === "scale";
this.helper[ "translate" ].visible = this.mode === "translate";
this.helper[ "rotate" ].visible = this.mode === "rotate";
this.helper[ "scale" ].visible = this.mode === "scale";
}
```
Live example:
* [jsfiddle](https://jsfiddle.net/kmturley/2p1v6bcw/20/)
* [Somone else's example](http://projects.defmech.com/ThreeJSObjectRotationWithQuaternion/)
##### Three.js version
- [x] Dev
- [x] r112
##### Browser
- [x] All of them
- [ ] Chrome
- [ ] Firefox
- [ ] Internet Explorer
##### OS
- [x] All of them
- [ ] Windows
- [ ] macOS
- [ ] Linux
- [ ] Android
- [ ] iOS
##### Hardware Requirements (graphics card, VR Device, ...)
None
2 Likes
You may be interested in this thread
3 Likes
drcmda
March 12, 2021, 11:26pm
4
the first part, disabling, yes, by listening to events: gltf simple example (forked) - CodeSandbox this one disables orbit when you click the transform objects which are also just meshes. this is react but the logic would be the same. listen to events, then switch on/off the controls you like.
as for enabling orbit controls only on a mesh, just enable them on pointer over and disable on pointer out.
1 Like