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.
Related
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
I have a threejs scene view containing a mesh, a perspective camera, and in which I move the camera with OrbitControls.
I need to add a measurement grid on a threejs view which "face" my perspective camera
It works on "start up" with the following code by applying a xRotation of Pi/2 on the grid helper
window.camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.01, 300 );
window.camera.position.z = 150;
window.grid1 = new THREE.GridHelper(500, ~~(500 * 2))
window.grid1.material.transparent = true;
window.grid1.material.depthTest = false;
window.grid1.material.blending = THREE.NormalBlending;
window.grid1.renderOrder = 100;
window.grid1.rotation.x = Math.PI / 2;
window.scene.add(window.grid1);
window.controls = new OrbitControls(window.camera, window.renderer.domElement );
window.controls.target.set( 0, 0.5, 0 );
window.controls.update();
window.controls.enablePan = false;
window.controls.enableDamping = true;
But once i start moving with orbitcontrol the grid helper don't stay align with the camera.
I try to use on the renderLoop
window.grid1.quaternion.copy(window.camera.quaternion);
And
window.grid1.lookAt(window.camera.position)
Which seems to work partially, gridhelper is aligned on the "floor" but not facing the camera
How can I achieve that?
Be gentle I'm starting with threejs :)
This is a bit of a hack, but you could wrap your grid in a THREE.Group and rotate it instead:
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.01, 300 );
camera.position.z = 150;
const grid1 = new THREE.GridHelper(500, ~~(500 * 2));
grid1.material.transparent = true;
grid1.material.depthTest = false;
grid1.material.blending = THREE.NormalBlending;
grid1.renderOrder = 100;
grid1.rotation.x = Math.PI / 2;
const gridGroup = new THREE.Group();
gridGroup.add(grid1);
scene.add(gridGroup);
// ...
And then, in your render loop, you make your group face to the camera (and not the grid):
gridGroup.lookAt(camera.position)
This works because it kind of simulates the behaviour of setting the normal in a THREE.Plane. The GridHelper is rotated to be perpendicular to the camera, and the it is wrapped in a group with no rotation. So by rotating the group, the grid will always be offset so that it is perpendicular to the camera.
I am creating a little multiplayer game basing on this three.js pointerlock example
I need to rotate the enemies avatars on the actual player screen, so he can see the direction they are looking at, but I cannot figure out how to properly do it
At the moment each enemy is sending an object with his position and rotation to the server
{
position: controls.getObject().position,
rotation: controls.getDirection(new THREE.Vector3())
}
the server receives it and sends to the actual player who with a function selects the respective enemy mesh (avatar) in the map and applies the position/rotation to it
var object = scene.getObjectByName(data.player);
object.position.x = data.position.x;
object.position.y = data.position.y;
object.position.z = data.position.z;
object.rotation.x = data.rotation.y;
object.rotation.y = data.rotation.x;
object.rotation.z = data.rotation.z;
But only the position works, the rotation is not working properly: the resulting rotation axes seem to be inverted and they also vary depending on the direction the actual player is looking at
Edit:
I tried also to "clone" it into another camera with different rotation.order as described here
var camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
camera2.rotation.order = 'YXZ';
var yawObject = controls.getObject();
var pitchObject = yawObject.children[0];
camera2.rotation.set(pitchObject.rotation.x, yawObject.rotation.y, 0);
and making enemies send
{
position: controls.getObject().position,
rotation: camera2.rotation
}
but rotation is still wrong
I realised that I can rotate objects into pointerlock direction in this way:
var dir = controls.getDirection(new THREE.Vector3());
var dis = 100;
mesh.lookAt({x:d.x * dis, y:d.y * dis, z:d.z * dis});
so I can make enemies send their direction instead of rotation, then make them look at a small distance in that direction.
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.
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