Conflict of LookAt and controls in three.js - javascript

I am preparing an application which shows a 3D model of a building and it works fine now. I was trying to control "PerspectiveCamera" using LookAt. However, I noticed LookAt does not work when I have the following line in animate function.
controls.update(1);
Therefore, I disabled this line (see below):
function animate(time) {
requestAnimationFrame( animate );
//controls.update(1);
TWEEN.update(time);
renderer.render( scene, camera );
}
However, I lose my mouse control (cannot zoom in/out) when I disable that line. If I enable that line , LookAt does not work properly.
Any suggestion? Thanks.

Just call camera.lookAt() in the animation loop if you're using the controls. That will get it to re-point to whatever you want to lookAt() after you've moved things around with the controls.

Related

ThreeJS/Panolens: direction of the camera when panorama entered?

I'm trying to throw an equirectangular image into Panolens and simply 1st get the same panorama viewer as can be visible below:
https://threejs.org/examples/webgl_panorama_equirectangular.html
https://www.chiefarchitect.com/products/360-panorama-viewer/
Since Panolens.js is a wrapper of Three.js I expected the same result as when I throw my image into the 1st link above. (drag & drop it) - camera looks into the center of the image.
What I get instead is : camera looks into the left most area of the panorama image.
I solve this using
panorama.addEventListener( 'enter-fade-start', function() {
viewer.getControl().target.set(10, -2, 0);
viewer.getControl().update();
//viewer.tweenControlCenter( new THREE.Vector3(2, -1, 1), 2000 );
});
But when I move to another panorama and come back, this code does not seem to have any effect (althought event is properly triggered).
How can I make the camera look into the same direction each time I come back to my panorama? (I'm switching between multiple panoramas).
Basically I don't seem to understand vectors properly and where 0,0,0 is each time I come back to panorama, since It seems to be working differently based on where the camera is facing.
Any tips/links/explanations very much welcome.
I over complicated things it seems. The solution is to only use:
viewer.tweenControlCenter( new THREE.Vector3(10, -2, 0), 0 );
inside "enter-fade-start". And that's it.
Much of docs is a bit misleading with saying you have to call .update() on control and setting .target properly etc, but that does not seem to work as I expected.
Relevant example also here: https://codepen.io/pchen66/pen/LLgxME

How to stop the controls from moving the cube with the mouse (gift/page2)

(gift/page2)
in this code: https://www.songnes.com/gift/page2.html
you can see a working example of a red cube rotating.
But I want to stop from moving the cube, using the mouse, or the fingers in the iPad.
I want to keep the cube in the same place.
Rotating YES! but not moving in space...
I comment this line
// let controls;
and this one
controls = new THREE.OrbitControls( camera, renderer.domElement );
but the code won't work. I would like waht am I doing wrong or how to solve this...
if you want to see the full code see this .txt file: https://www.songnes.com/gift/page2.txt
thank you
P.S. I don't know how to put the code here, yet (any video showing how)
You don't need to delete controls, just add this line :
controls.enabled = false;

Three.js Move object forward without translateZ

Like in lots of other similar questions, I want to move an object forward in three.js based on its rotation. The difference is, I can't use object.translateZ. This is because I'm using a physics simulator and it will mess up if I update the object like that. Here is an example fiddle of my problem. Feel free to play around with my fiddle and add your updated version to your answer.
I would like the cube to move forward by updating mesh.position.x and mesh.position.z based on mesh.rotation.y.
To keep in mind, I've sometimes realized that three.js rotations are a little weird some times when accessing them using mesh.rotation.y.
Thanks!
I would suggest using the mesh.getWorldDirection() to get a direction where you want to move your mesh. Then you can multiply it with a scalar to adjust movement speed.
direction = mesh.getWorldDirection();
mesh.position.add(direction.multiplyScalar(moveSpeed));
Fiddle: https://jsfiddle.net/k1swrxjr/1/
Good luck!
To move your mesh simply increment the value of the position in which you want your mesh to go in you animate() function instead of init function, example as follows:
function animate() {
mesh.position.x += 0.1;
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
This example code will increase x position of your mesh by 0.1 every time animate() is run.

How can I apply TrackballControls to a moving target?

I would like to apply the three.js script TrackballControls to a moving object in a way that preserves the ability to zoom and rotate the camera while the object moves through the scene. For example, I would like to be able to have the camera "follow" a moving planet, while the user retains the ability to zoom and rotate around the planet. Here is a basic jsfiddle:
http://jsfiddle.net/mareid/8egUM/3/
(The mouse control doesn't actually work on jsfiddle for some reason, but it does on my machine).
I would like to be able to attach the camera to the red sphere so that it moves along with it, but without losing the ability to zoom and rotate. I can get the camera to follow the sphere easily enough by adding lines like these to the render() function:
mouseControls.target = new THREE.Vector3(object.position);
camera.position.set(object.position.x,object.position.y,object.position.z+20);
But if I do that, the fixed camera.position line overrides the ability of TrackballControls to zoom, rotate, etc. Mathematically, I feel like it should be possible to shift the origin of all of the TrackballControls calculations to the centre of the red sphere, but I can't figure out how to do this. I've tried all sorts of vector additions of the position of the red sphere to the _this.target and _eye vectors in TrackballControls.js, to no avail.
Thanks for your help!
I'd recommend OrbitControls rather than TrackballControls. My answer here applies primarily to OrbitControls; the same principle might also work with TrackballControls (I have not looked at its code in a while).
If you look at how OrbitControls works you should notice it uses this.object for the camera, and this.target for where the camera is looking at, and it uses that vector (the difference between them) for some of its calculations. Movement is applied to both positions when panning; only the camera is moved when rotating. this.pan is set to shift the camera, but out of the box it only deals with a panning perpendicular to the this.object to this.target vector because of the way it sets the panning vector.
Anyway, if you subtract the vector from object.position to controls.target and set controls.pan to that vector, that should make it jump to that object:
Fixed example code:
Add a helper to OrbitControls.js which has access to its local pan variable:
function goTo( vector ) {
// Cloning given vector since it would be modified otherwise
pan.add( vector.clone().sub( this.target ) );
}
Your own code:
function animate() {
requestAnimationFrame(animate);
mouseControls.goTo( object.position ); // Call the new helper
mouseControls.update();
render();
}
You'll also probably want to set mouseControls.noPan to true.

Pausing/turn off three.js TrackballControls

I'm using TrackballControls to rotate the camera in my scene using the mouse but also need to be able to rotate individual objects in the scene using the mouse. I'd like to be able to toggle on/off TrackballControls to accomplish this. However, so far there are issues with everything I've tried. This is how my controls are defined:
var controls; // global
inside init():
controls = new THREE.TrackballControls( camera );
controls.addEventListener( 'change', render );
and finally in animate():
controls.update();
So far, I've tried:
Removing the event listener like this: controls.removeEventListener( 'change', render ); which didn't change anything; controls worked the same as it always has.
Conditionally updating the controls like this:
(global)
var enableControls = true;
(in animate)
if (enableControls == true) {
controls.update();
}
and then toggling enableControls using a KeyDown event. This seemed to work, because when enableControls was false I could rotate an object without moving the camera. However, when I update again, the camera moves significantly (it moves to where it would have been based on my clicking/dragging done while I wasn't updating).
I tried both of these separately and in conjunction with one another with no luck.
To disable TrackballControls, all you need to do is set
controls.enabled = false;
Also, you likely do not need controls.addEventListener( 'change', render ); since you are calling controls.update() in the animation loop.
three.js r.67

Categories