Reputation: 14815
I'm displaying an OBJ element with Three.js using WebGlRenderer, now I'd like to allow users to rotate the camera around the object in any direction, I've found this answer:
Rotate camera in Three.js with mouse
But both examples return me errors, the first says that projector is not defined, and I don't know what it means with "projector". I've just a simple camera, the object and some light. The second code says that undefined is not a function.
Does someone know how to get the result I need?
Upvotes: 19
Views: 49141
Reputation: 253
If you don't want to mess with OrbitControls
, simply add the camera to a boom Group
const boom = new THREE.Group();
boom.add(camera);
scene.add(boom);
camera.position.set( 0, 0, 100 ); // this sets the boom's length
camera.lookAt( 0, 0, 0 ); // camera looks at the boom's zero
then you can rotate this boom instead of the camera itself.
boom.rotation.x += 0.01;
You may want to add some extra objects, like lights etc. to this boom, btw
Upvotes: 5
Reputation: 969
If you are using ES6, following could be used for OrbitControls
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// this would create the orbit controls
// it would allow camera control using mouse
const orbitControls = new OrbitControls(camera, renderer.domElement);
If you need autorotate,
function init() {
...
// following would enable autorotate
const orbitControls.autoRotate = true;
..
}
function animate() {
// need to update the orbitcontrols for autorotate camera to take effect
orbitControls.update();
...
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
For ref: https://threejs.org/docs/#examples/en/controls/OrbitControls
Upvotes: 1
Reputation: 11221
Here is a quick hack, in case you don't want to use the OrbitControls for some reason.
camera.position.copy( target );
camera.position.x+=Math.sin(camera.rotationy)*3;
camera.position.z+=Math.cos(camera.rotationy)*3;
camera.position.y+=cameraHeight; // optional
tempVector.copy(target).y+=cameraHeight; // the += is optional
camera.lookAt( tempVector );
camera.rotationy is a copy of the mouse rotation value since we are changing it with the call to lookAt.
Upvotes: 2
Reputation: 1
Extra info for who looking auto rotate direction change on a limit:
if (
controls.getAzimuthalAngle() >= Math.PI / 2 ||
controls.getAzimuthalAngle() <= -Math.PI / 2
) {
controls.autoRotateSpeed *= -1;
}
controls.update();
Upvotes: 0
Reputation: 45042
Add a listener to trigger render method on change of OrbitControl
:
const controls = new OrbitControls(camera, this.renderer.domElement);
controls.enableDamping = true; //damping
controls.dampingFactor = 0.25; //damping inertia
controls.enableZoom = true; //Zooming
controls.autoRotate = true; // enable rotation
controls.maxPolarAngle = Math.PI / 2; // Limit angle of visibility
controls.addEventListener("change", () => {
if (this.renderer) this.renderer.render(this.scene, camera);
});
and in animate update controls:
start = () => {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate);
}
};
stop = () => {
cancelAnimationFrame(this.frameId);
};
renderScene = () => {
if (this.renderer) this.renderer.render(this.scene, camera);
};
animate = () => {
// update controls
controls.update();
}
Upvotes: 0
Reputation: 2286
This is what you want: http://threejs.org/examples/misc_controls_orbit.html
Include the orbit controls (after you have downloaded them):
<script src="js/controls/OrbitControls.js"></script>
Setup the variable:
var controls;
Attach the controls to the camera and add a listener:
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
and in your animate function update the controls:
controls.update();
[Update] controls.autoRotate = true;
(tested in v73. Recent versions of OrbitControls.js has added this control.)
Upvotes: 37
Reputation: 1365
Indeed, if you substitute 'camera' with the object of your choice, the object will rotate. But if there are other objects surrounding it (for example a grid on the floor), they will still stand still. That might be what you want, or it might look weird. (Imagine a chair rotating floating above the floor...?)
I choose to override the center object from OrbitControls.JS from my code after initializing the Orbit Controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
…
controls.center = new THREE.Vector3(
chair.position.x,
chair.position.y,
chair.position.z
);
(disclaimer: I have the impression there are different versions of OrbitControls.js around, but I assume they all use this center-object)
Upvotes: 1