I have a THREE.PerspectiveCamera to which I add a THREE.CameraHelper.
cameraLocal = new THREE.PerspectiveCamera(70, 1, 20, 120);
scene.add(cameraLocal);
cameraLocalHelper = new THREE.CameraHelper(cameraLocal);
cameraLocal.add(cameraLocalHelper);
However when I rotate the camera,
cameraLocal.rotateX(0.1);
the CameraHelper rotates by a larger amount than the camera.
I've made a
demo that shows this.
Initially, cameraLocal can't see the help lines drawn by the CameraHelper. However, if cameraLocal is rotated either way about the x-axis, the help lines come into view, I'm supposing on account of the CameraHelper rotating by a different amount.
Could anyone point out what I'm doing wrong here?
I'm using the build of three.js from 5-Aug-2019.
CameraHelper needs to be added directly to the scene.
Do not try to add it as a child of the camera itself.
three.js r.107
Related
What I have is an OrthographicCamera set up so that is has an isometric view of the scene and OrbitConrols added to allow for panning around and zooming but not for rotation.
What I’d like to have is a button that will centre the objects in a scene and zoom the OrthographicCamera so that the objects fit within the canvas area while keeping the isometric view, i.e. the angle between the camera.position and the camera.lookAt (control.target) point.
What I’ve tried is to set the controls.target at the centre of the bounding box of the objects in the scene.
I have 2 problems with the code at the moment.
The First is I couldn’t work out how to calculate the zoom level needed to make sure the objects in the scene are all in view. I’ve hard coded a value for just now.
The Second is that with the current code, if the camera is panned so that the objects appear nearly off the screen, either up or down, then when centred the angle of the camera changes. This was happening when the camera was panned far left or right but setting the max and min Azimuth Angle seems to prevent this.
camera rotates after centring
The image above shows the scene when loaded then after centering when the camera was panned so the objects were going off the top of the screen.
I have tried a number of ways to do this after looking at answers to similar questions as this but am still having problems getting it to work.
function fitDrawingToPage(){
// Variables Bbox etc are set outside the function
Bbox = new THREE.Box3();
for (const object of sceneObjects) Bbox.expandByObject(object);
newTarget = Bbox.getCenter(new THREE.Vector3());
controls.target.set( newTarget.x, newTarget.y, newTarget.z );
controls.update();
camera.zoom = 0.5;
camera.updateProjectionMatrix();
camera.updateMatrix();
render();
}
current example of code in jsfiddle
I have created a raytracing algorithm which currently displays a triangle on screen, and am now having trouble moving the camera around correctly.
I would like my code to have the arrow keys rotate the camera, and WASD move the camera in 3D space. The camera currently rotates correctly using two rotation matrices for y and z rotations.
The Problem
Moving the camera, rather than rotating, is where the issue arises. To move the camera, I require two vectors - cameraForward and cameraRight. These vectors can be added on to the position of the camera when input is detected. These vectors will also need to change when the cemara is rotated, in the same rotation as all the rays experience. But when I apply these rotation matrices to the vectors representing cameraRight and cameraForward, there seems to be an issue. Holding down the A or D key will result in the camera moving unexpectedly in circles or odd wavy lines.
I managed to fix the issue with cameraForward by using a different method. I added a couple lines of code which calculate when the ray at the centre as been 'fired' and proceed to set cameraForward to that ray. Therefore cameraForward will always follow the central ray being sent out i.e. the centre of the field of view. However, I cannot do the same with cameraRight, as this vector is not in the field of view.
Before solving cameraForward using this method the same issue arose with moving forwards and backwards.
I also tried taking the cross product of one of the other rays along with the cameraForward vector which I thought might produce cameraRight, but to no avail - more sporadic camera movement
I do not have the vector for cameraUp either so cannot calculate the cross product to find cameraRight.
I also thought maybe the code was being run too many times and the vector was rotated multiple times. However mvoing the code elsewhere had no effect and the method it was already in is run every frame, so I do not believe that is the issue.
Here is my code to rotate the camera right and the method which does the rotation.
camRight's inital value is (0, 0, 1)
camRight = normalize(rotateVector(camRight, rotationZ));
camRight = normalize(rotateVector(camRight, rotationY));
function rotateVector(v, m) {
return new Vector3(dot(m.a, v), dot(m.b, v), dot(m.c, v));
}
I know this code works as the code rotating the camera view functions correctly using the same matrices and methods.
(the following code)
myDirection = normalize(rotateVector(myDirection, rotationZ));
myDirection = normalize(rotateVector(myDirection, rotationY));
When the user presses A or D the following code is run
if (keys[65]) {
camPos = add(camPos, normalize(camRight));
requestAnimationFrame(render);
}
if (keys[68]) {
camPos = subtract(camPos, normalize(camRight));
requestAnimationFrame(render);
}
The camera moves forwards and backward correctly, as previously mentioned. Initially, the camera moves left and right correctly too (as its inital value of (0, 0, 1) is correct), but if I rotate the camera, the values for cameraRight go wild.
Have I assumed something wrongly? or is there a flaw in my logic somewhere?
Thank for any help
I am writing a 3d game in javascript with threejs. I made a skybox, and it works, but if I make my cameras near and far distances too small it doesn't show.
I understand why this happens, the camera attached to my player doesn't see as far as the skybox. If I make my cameras "near" and "far" attributes large enough (corresponding to the size of my game map) I can make it so that my skybox is always within range, but I don't want that, since I don't want the camera to see all the objects that far away.
Any ideas of how to force the camera to see the skybox but still have a small "far" attribute so as to no see all the objects in the world?
Any help would be greatly appreciated.
There’s scene.background, which can be set to a CubeTexture.
Just want to add an example, because someone might find it useful here:
var loader = new THREE.CubeTextureLoader();
loader.load([
'./img/sky/galaxy-X.jpg', './img/sky/galaxy+X.jpg',
'./img/sky/galaxy-Y.jpg', './img/sky/galaxy+Y.jpg',
'./img/sky/galaxy-Z.jpg', './img/sky/galaxy+Z.jpg'
] , function(texture)
{
scene.background = texture;
});
I'm trying to position a part of a texture that is being rendered on a portion of a SphereGeometry, inside a full SphereGeometry.
I attach a jsfiddle so you can see what I mean:
https://jsfiddle.net/ggL3uemh/23/
If you open the link, you will see that the smaller texture in the scene is a part of the bigger one.
The bigger one is rendered on a big full sphere.
The smaller one, is rendered on a portion of a sphere.
I want to give the smaller Mesh the proper position, rotation and scale so it can perfectly fit inside the sphere making it look like the smaller one isn't even there.
I suspect the part of the sphere is not correct either...
this.videoCustomGeometry = new THREE.SphereBufferGeometry(500, 64, 64, 1, 1.8, 1, 0.9);
this.videoCustomGeometry.scale( - 1, 1, 1 );
I came close to find the position, using a raycaster and attaching the next code to the mousemove event:
this.raycaster.setFromCamera(this.mouse, this.camera);
var intersects = this.raycaster.intersectObjects([this.pano], false);
And then, I get the exact position where the smaller Mesh should be positioned, but I don't know about the rotation, scale, or if the geometry the smaller Mesh is using is correct.
I'm stuck... thanks in advance!
I am currently creating a VR web app using three.js. As the camera controls I am using the device orientation controls used here in the google cardboard three.js demo.
What I need to do is add keyboard controls to this(e.g Up arrow to go forward etc). I've fiddled around with moving the camera on the two axis (x and z) here:
if (e.keyCode == '38') {
camera.position.set(0, 10, camera.position.z+4);
controls.target.set(
camera.position.x +4,
camera.position.y,
camera.position.z
);
effect.render(scene, camera);
...
However I want to make the character move relative to where they are looking (e.g You look one way and press the Up arrow and the character moves the way you looking). Like a first person view.
Does anyone have any ideas on how this is done? Ive tried using the first person controls from three.js but this eliminates the head tracking which is essential for a VR game.
Any answers would be greatly appreciated. (My source code is practically just the Google cardboard three.js demo code with a function added in too detect key presses)
I solved this by different approach. I created an object3d which is moving in scene. Model and camera are child of this object.
I'm rotating object 3d with camera and in the same time rotate model in opposite direction. When i rotate camera object looks keeping direction. when i want to move object, just translateX object with camera and make model rotation to 0. That did the trick.
On long distances (I have millions of units) started to be jerky. Reason is lost precision.
I solved it by keeping position of object at 0,0,0 and move all other things in opposite direction. That makes your model is still on 0,0,0 coords with right rotation and world is moving around.
Most simple example:
you trying something like
scene.add(character_model);
scene.add(camera);
//camera.rotate ....
character_model.translateX(1);
character_model.rotateX(1);
//etc ...
and now you trying to move camera around the pivot (character_model), but this is overcomplicated mathematics.
Try:
var controls_dimension = new THREE.Object3D();
scene.add(controls_dimension);
controls_dimension.add(character_model);
controls_dimension.add(camera);
//use controls to rotate with this object, not with character_model
controls_dimension.rotateX(2);
// in the same rotate model to opposite direction. You can make
// illusion of rotating camera, not a model.
character_model.rotateX(2*-1);
/*
when you want to go in camera direction=controls_dimension=controls_dimension.translateX(1)
and we moving (you most only animate model rotation to controls_dimension.rotation)
*/