I am making a game in three.js and I have 2 questions. 1. I have a cube which gets pushed along but every few seconds it "Jitters" back a little. Why?. 2. When i click the left or right arrow key the cube meant to rotate on its Y-axis instead of rotating one way it sometimes rotates a little one way and then the other?.
So I realised that I was updating the camera in the Renderer update function not the physics update function so I moved it and now there is no jittering. Also for the rotation I changed .rotation.y -= 0.1; to .rotateOnAxis( new THREE.Vector3(0,1,0), -0.05); and now it works.
Related
I need to get the camera up direction and i've tried many ways with no luck, i'm not an expert of quaternions so i'm doubting i did it right.
I've tried:
camera.up
camera.up.applyMatrix4(camera.matrixWorld);
new THREE.Vertex3(0,1,0).applyMatrix4(camera.matrixWorld);
camera.up.normalize().applyMatrix4(camera.matrixWorld);
after this i create two planes passing by two points of my interest, and add the plane helper to the scene and i can see they are very far from where i was expecting them. (i'm expecting two planes that looks like the top and bottom of the camera frustum).
P.s. the camera is a shadow camera of a directional light so an orthographic camera, and i manipulate the directional light position and target before doing this operation, but i've called updateMatrixWorld on the light, on it's target and the camera, on the camera i've called also updateProjectionMatrix... still no results
I've made a sandbox to see what i've tried till now, and better visualize what i want to achieve:
https://codesandbox.io/embed/throbbing-cache-j5yse
once i manage to get the green arrow to point to the top of the blue triangle of the camera helper i'm good to go
In the normal render flow, shadow camera matrices are updated as part of rendering the shadow map (WebGLShadowMap.render).
However, if you want the updated matrix values before the render, then you'll need to update them manually (you already understand this part).
The shadow camera is a property of (not a child of) the DirectionalLight. As such, it doesn't follow the same rules as other scene objects when it comes to updating its matrices (because it's not really a child of the scene). Instead, you need to call the shadow property's updateMatrices method (inherited from LightShadow.updateMatrices).
const dl = new THREE.DirectionalLight(0xffffff, 1)
dl.shadow.updateMatrices(dl) // <<------------------------ Updates the shadow camera
This updates the shadow camera with information from the DirectionalLight's own matrix, and its target's matrix, to properly orient the shadow camera.
Finally, it looks like you're trying to get the "world up" of the camera. Personally, I'd use the convenience function localToWorld:
let up = new THREE.Vector3(0, 1, 0)
dl.shadow.camera.localToWorld(up) // destructively converts "up" from local-to-camera into world coordinates
via trial and errors i've figured out that what gave me the correct result was:
calling
directionalLight.shadow.updateMatrices(...)
and then
new THREE.Vector3(0,1,0).applyQuaternion(directionalLight.shadow.camera.quaternion)
I need to be able to change rotation pivot without changing camera lookAt on THREE.TrackballControls no mater what I tried I could not succeed. Please give me a direction to solve this problem. What I am actually trying to achieve is Revit like mouse controls.
I was able to solve this problem by creating 2 3D objects named orbit and target, then add target and camera into orbit as child objects... camera always looks at target.position, mousemove on x axis rotates the orbit object around Z axis (hence target and camera rotates around the orbit) and mousemove on y axis rotates the camera arm (camera.position vector) around cameraSideways direction.
I'm working on a simple Three.js demo that uses OrbitControls.js.
I'd like to change the behavior of panning in OrbitControls. Currently, when you pan the camera, it moves the camera in a plane that is perpendicular to the viewing direction. I'd like to change it so that the camera stays a constant distance from the ground plane and moves parallel to it. Google Earth uses a similar control setup.
Edit: I should have mentioned this detail in the first place, but I'd also like the point where you click and start dragging to remain directly under the cursor throughout the entire drag. There needs to be that solid connection between the mouse movement and what the user expects to happen on the screen. Otherwise, it feels as though I'm 'slipping' when I try to move around the scene.
Can someone give me a high-level explanation of how this might be done (with or without OrbitControls.js)?
EDIT: OrbitControls now supports panning parallel to the "ground plane", and it is the default.
To pan parallel to screen-space (the legacy behavior), set:
controls.screenSpacePanning = true;
Also available is MapControls, which has an API similar to that of Google Earth.
three.js r.94
Some time ago I was working on exactly this issue, i.e. adaptation of OrbitControls.js to map navigation.
Here's the code of MapControls.js.
Here's the demo of the controls.
I figured it out. Here's the overview:
Store the mousedown event somewhere.
When the mouse moves, get the new mousedown event.
For each of those points, find the points on the plane where those clicks are located (You'll need to put the points into camera space, transform them into world space, then fire a ray from the camera through each point to find their intersections with the plane. This page explains the ray-plane intersection test).
Subtract the world-space start intersection point from the world-space end intersection point to get the offset.
Subtract that offset from the camera's target point and you're done!
In the case of OrbitControl.js, the camera always looks at the target point, and its position is relative to that point. So when you change the target, the camera moves with it. Since the target always lies on the plane, the camera moves parallel to that plane (as long as you're panning).
You should set your camera 'up' to z axe:
camera.up.set(0,0,1)
And then, the main problem with OrbitControl is its panUp() function. It should be fixed.
My pull request : https://github.com/mrdoob/three.js/pull/12727
y axe is relative to camera axes and should be relative to a fixed plan in the world. To define the expected y axe, make a 90° rotation of camera x axe, based on world z axe.
v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
v.applyAxisAngle( new THREE.Vector3( 0, 0, 1 ), Math.PI / 2 );
v.multiplyScalar( distance );
panOffset.add( v )
Enjoy!
I'm playing around with Three.js, and I'm trying to figure out how to keep a box I have always facing away from the camera.
As of right now, the camera rotates around the box as you drag around. However, the box itself does not rotate. I want to make it so that as you rotate the camera, the box's yaw changes to face away from the camera.
How would I accomplish something like this? At first, I tried to set the .rotation.y of the box to the .rotation.y of the camera, however that didn't work
What you are describing should work. I have made a fiddle you can check out and compare your code to: fiddle
Here is a snippet from the animate function:
//quick and dirty way to spin the camera around the world center
camera.position.set(0, 0, 0); //move to world center
camera.rotation.y += 0.01; //rotate camera around world center
camera.translateZ(300); //move backwards
//match
cube1.rotation.y = camera.rotation.y;
If you post your code here or on JSFiddle I might be able to help figure out what in your code is misbehaving
I'm new to libGDX and android game dev. And I want to achieve this:
I have a Screen and within it, a ball sprite that is moving along the X axis. Now I want to center the viewport to the sprite when it moves. Just like in Angry birds, where the camera follows the bird flying across the sky.
How can I implement that within my game using OrthographicCamera?
This took me a while of Googling and testing, but I just found something and I think others may appreciate it.
To move the camera (and if you are using a spriteBatch), make sure to call setProjectionMatrix.
Ex:
camera.position.y += 5; // or whatever you want to change y by...
camera.position.x += 5;
camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
Hope this helps someone!
In case you haven't figured this out yet, you need to convert the ball position to the camera position using
camera.unproject(ballPosition)
This converts the screen coordinates into world coordinates. Then call
camera.position(ballPosition)
to set the camera position to your ball's location in the world.
The
camera.translate(...);
function translates all of the involved attributes the camera by the given data. After the operation you need to call
camera.update();
to calculate the new matrices of the camera. This will push the camera to the direction you want.