setting camera rotation changes camera's position - three.js

when i have the following code:
camera = new THREE.PerspectiveCamera( 45, width/height, 1, 10000 );
scene.add( camera );
camera.rotation.set(-0.09388335, 0.9945234, 0.0474389);
camera.position.z = 100;
camera.rotation.set(-0.09388335, 0.9945234, 0.0474389);
at render time the position of camera.matrixWorldInverse changes. Anyone knows why?
My guess is that because you are rotating the camera's rotation locally you are changing its position globally. If that's the case then why would the rotate around world axis in the following work:
How to rotate a object on axis world three.js?

I was looking at camera.matrixWorldInverse not camera.matrixWorld

Related

How to make THREE.OrbitControls spin a plane around Z-axis (& X-axis)

I have a PlaneGeometry & mesh, extent is X,Y, normal is Z-axis
And a camera centered above that plane looking down from +Z axis.
(basically looking down a the plane which is a topo/terrain map)
By default, OrbitControls will rotate the view around the X & Y axis.
(which is fairly useless in this case)
What [mostly] works is the rotate the scene around the X-axis scene.rotateX(-Math.PI/2)
and then drive the camera/view to be above the Z-axis.
After that, OrbitControls do the right thing:
vertical mouse tilts the view down to (or up from) the plane
horizontal mouse spins the plane around the z-axis (so can see from the other direction)
Two 'problems':
Is there an API to set the OrbitControl to be above the Z-axis?
(after scene.rotateX, the view is at elevation 0, looking across the plane)
I'd like to rotate the camera/view to above the Z-axis at altitude.
Is there an alternative way to get OrbitControls to select which axis to rotate?
(so without the scene.rotateX, the camera is in the right place)
There's a related fiddle (ignore the SpotLight): https://jsfiddle.net/4azo5bvf/65/
Edit:
const camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 100 );
camera.position.set(0, 0, 50);
camera.up.set(0, 0, 1); // <=== spin around Z-axis
const ob_controls = new THREE.OrbitControls(camera, canvas);
So we can mark this as 'answered' (thanks to #WestLangley)
The easy solution is to use camera.up.set(0, 0, 1)
Apparently, OrbitControls uses that to determine the rotatonal/axial orientation.
const camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 100 );
camera.position.set(0, 0, 50);
camera.up.set(0, 0, 1); // <=== spin around Z-axis
const ob_controls = new THREE.OrbitControls(camera, canvas);
After further review (and TerekC's answer in Three.JS rotate projection so that the y axis becomes the z-axis) changed to use:
THREE.Object3D.DefaultUp.set(0, 0, 1); // Z-axis up, and spinable

Set camera left/right

I have a three.js animation of a person running. I have embedded this in an iFrame on my site however the character runs off the screen.
I am very happy with the positioning and the camera angle, I just need to move it right so that the character is centred in the iFrame.
Below is the code I am using.
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 4000);
camera.position.set(0, 150, 50);
camera.position.z = cz;
camera.zoom = 3.5;
camera.updateProjectionMatrix();
scene.add(camera);
You could use the camera.lookAt() method, which will point the camera towards the desired position.
// You could set a constant vector
var targetPos = new THREE.Vector3(50, 25, 0);
camera.lookAt(targetPos);
// You could also do it in the animation loop
// if the position will change on each frame
update() {
person.position.x += 0.5;
camera.lookAt(person.position);
renderer.render(scene, camera);
}
I feel like the lookAt() method wouldn't work. It will just rotate the camera, and you specified you like the camera placement/angle.
If you want to move the camera to the right along with you model, set the camera's position.x equal to model.x for every frame(assuming left/right is still the X axis).
person.position.x += 0.5;
camera.position.x = person.position.x;
Alternatively, you could keep the object and camera static and move the ground plane. Or even have a rotating cylinder with a big enough radius flipped on its side.

How to setup a camera that follows a circle path?

I'm trying to create a camera that follows an object that rotates on a orbit around a sphere. But everytime the camera reaches the polar coordinates of the orbit, the direction changes. I just set the position of the camera according to the object that is has to follow and calling lookAt afterwards:
function render() {
rotation += 0.002;
// set the marker position
pt = path.getPoint( t );
// set the marker position
marker.position.set( pt.x, pt.y, pt.z );
marker.lookAt( new THREE.Vector3(0,0,0) );
// rotate the mesh that illustrates the orbit
mesh.rotation.y = rotation
// set the camera position
var cameraPt = cameraPath.getPoint( t );
camera.position.set( cameraPt.x, cameraPt.y, cameraPt.z );
camera.lookAt( marker.position );
t = (t >= 1) ? 0 : t += 0.002;
renderer.render( scene, camera );
}
Here's a complete fiddle: http://jsfiddle.net/krw8nwLn/69/
I've created another fiddle with a second cube which represents the desired camera behaviour: http://jsfiddle.net/krw8nwLn/70/
What happens is that the camera's lookAt function will always try to align the camera with the horizontal plane (so that the "up" direction is always (0, 1, 0). And when you reach the top and bottom of the ellipse path, the camera will instantaneously rotate 180° so that up is still up. You can also see this in your "desired behaviour" example, as the camera cube rotates so that the colors on the other side are shown.
A solution is to not use lookAt for this case, because it does not support cameras doing flips like this. Instead set the camera's rotation vector directly. (Which requires some math, but you look like a math guy.)

Lens Flare strange rotation while rotating camera

While rotating camera, lens flare has some rotation based on camera angle, please see this fiddle: http://jsfiddle.net/e4kf3u7t/1/
I want to avoid that, making lens flare always facing camera without rotation, like Sprite behavior: http://jsfiddle.net/e4kf3u7t/3/
Sample code:
var flareColor = new THREE.Color( 0xffffff );
var lensFlare = new THREE.LensFlare( textureFlare0, 200, 0.0, THREE.NormalBlending, flareColor );
lensFlare.position.y = 100;
lensFlare.position.z = 200;
scene.add(lensFlare);
The reason why I want to use Lensflare instead of Sprite is as you can see in fiddle, lens flare disappearing when it center hiding behind another geometry, Sprite doesn't act like that.

Why I only see parts of my BoxGeometry object in ThreeJS on zoom in/zoom out?

When the camera move back and forth a little, my Box object kind of disappear (screenshots below)
Camera object:
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
camera.position = new THREE.Vector3(0,-80,850);
I only zoom in/out using my mouse wheel.
The Boxes size:(48*1.5,70*1.5, 0.5)
What is causing this and how can I fix it?
Thanks !! :)
You're having precision issues because the range of the camera is too high.
Try with a smaller range:
camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
Also, change camera.position = new THREE.Vector3(0,-80,850) to camera.position.set(0,-80,850). This pattern may not work in the future.

Resources