Hello ThreeJS Community!
I am currently working on a clone of three js editor and recently I updated the EditorControls.js script to add damping in rotation and panning, to give the user a better experience while working with the camera in Editor. This script now resembles the OrbitControls.js script and implements rotation in same way as OrbitControls does.
I want to allow the user to be able to set the rotation vector of the camera that is active in the editor such as [x: 10, y: -5, z: 4] but whenever I try to update the rotation, it gets overridden by the EditorControls, similarly as it does in OrbitControls, and the values are reset by the update function in the script. I’ve tried the following approach:
- Disable the update function by setting this.enabled = false
- Resetting the values used by the update function
- Setting the rotation
- Enabling the update function
Below are the code snippets:
Code to be run when user update the rotation values from editor:
editor.signals.objectChanged.add(function (object, newRotation) {
if (object.uuid !== scope.camera.uuid || newRotation == undefined)
return;
console.log("object: ", object);
scope.enabled = false;
reset();
console.log("newRotation: ", newRotation);
scope.camera.rotation.copy(newRotation);
scope.camera.updateMatrixWorld( true );
scope.enabled = true;
// scope.update();
// controller.updateObject( object );
});
Reset function:
function reset() {
center = new THREE.Vector3();
scope.rotateDelta = new THREE.Vector2();
scope.rotateEnd = new THREE.Vector2();
scope.rotateStart = new THREE.Vector2();
scope.sphericalDelta = new THREE.Spherical();
quat = new Quaternion().setFromUnitVectors(scope.camera.up, new THREE.Vector3(0, 1, 0));
quatInverse = quat.clone().invert();
lastPosition = new THREE.Vector3();
lastQuaternion = new Quaternion();
vector = new THREE.Vector3();
scope.camera.updateProjectionMatrix();
// scope.update();
state = STATE.NONE;
}
rotate function:
this.rotate = function (event) {
this.rotateEnd.set(event.clientX, event.clientY);
this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart).multiplyScalar(this.rotationSpeed);
var element = domElement;
rotateLeft(2 * Math.PI * this.rotateDelta.x / element.clientHeight); // yes, height
rotateUp(2 * Math.PI * this.rotateDelta.y / element.clientHeight);
this.rotateStart.copy(this.rotateEnd);
scope.dispatchEvent(changeEvent);
setOrientation(this);
};
Update function:
this.update = function () {
return function update(delta) {
if (this.enabled === false) return;
if (!logicBlockToggle) {
// var actualMoveSpeed = delta * this.movementSpeed;
// var prevPos = this.camera.position.clone();
// if (this.moveForward || (this.autoForward && !this.moveBackward)) this.camera.translateZ(- (actualMoveSpeed + this.autoSpeedFactor));
// if (this.moveBackward) this.camera.translateZ(actualMoveSpeed);
// if (this.moveLeft) this.camera.translateX(- actualMoveSpeed);
// if (this.moveRight) this.camera.translateX(actualMoveSpeed);
// if (this.moveUp) this.camera.translateY(actualMoveSpeed);
// if (this.moveDown) this.camera.translateY(- actualMoveSpeed);
// center.add(this.camera.position.clone().sub(prevPos));
// if (this.moveForward || this.moveBackward || this.moveLeft || this.moveRight || this.moveUp || this.moveDown) {
// var actualLookSpeed = this.lookSpeed * delta;
// lon -= this.mouseX * actualLookSpeed;
// lat -= this.mouseY * actualLookSpeed;
// lat = Math.max(- 85, Math.min(85, lat));
// var phi = THREE.MathUtils.degToRad(90 - lat);
// var theta = THREE.MathUtils.degToRad(lon);
// vector.setFromSphericalCoords(1, phi, theta).add(this.camera.position);
// this.camera.lookAt(vector);
// }
this.applyKeyBoardMovement();
}
vector.copy(this.camera.position).sub(center);
vector.applyQuaternion(quat);
spherical.setFromVector3(vector);
if (this.heightSpeed) {
var y = THREE.MathUtils.clamp(this.camera.position.y, this.heightMin, this.heightMax);
var heightDelta = y - this.heightMin;
this.autoSpeedFactor = delta * (heightDelta * this.heightCoef);
} else {
this.autoSpeedFactor = 0.0;
}
if (this.enableDamping) {
spherical.theta += sphericalDelta.theta * this.dampingFactor;
spherical.phi += sphericalDelta.phi * this.dampingFactor
}
else {
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi
}
spherical.makeSafe();
if (this.enableDamping === true) {
center.addScaledVector(panOffset, this.dampingFactor);
} else {
center.add(panOffset);
}
spherical.radius *= scale;
spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
vector.setFromSpherical(spherical);
vector.applyQuaternion(quatInverse);
this.camera.position.copy(center).add(vector);
this.camera.lookAt(center);
scale = 1;
if (zoomChanged ||
lastPosition.distanceToSquared(this.camera.position) > EPS ||
8 * (1 - lastQuaternion.dot(this.camera.quaternion)) > EPS) {
// scope.dispatchEvent(changeEvent);
lastPosition.copy(this.camera.position);
lastQuaternion.copy(this.camera.quaternion);
zoomChanged = false;
// return true;
}
if (this.enableDamping) {
sphericalDelta.theta *= (1 - this.dampingFactor);
sphericalDelta.phi *= (1 - this.dampingFactor);
panOffset.multiplyScalar(1 - scope.dampingFactor);
}
else {
sphericalDelta.set(0, 0, 0);
panOffset.set(0, 0, 0);
}
this.smoothZoomUpdate();
};
}();
Looking forward to receiving your valuable advice.