THREE.JS : Rotate everyting (including camera) despite the orbit controller - javascript

Here is what I would like to do:
When a condition is verified, I would like to rotate everything on the scene, including the camera.
The user will not remark any difference since the camera still show exactly the same thing, but in fact the objects would be rotated.
Of course the orbit controller should still work...
The question might be silly, but I'm having troubles. Either the camera gets shifted and doesn't show the exact same thing or the orbit controller doesn't work.
How would you do?
Thanks.
EDIT: I should detail more what I tried.
So let's say the only thing I have on my scene is a cube with a number on each face.
Face 1 is pointing toward +X.
Face 2 is pointing toward +Y.
Face 3 is pointing toward +Z.
Face -1 is pointing toward -X.
Face -2 is pointing toward -Y.
Face -3 is pointing toward -Z.
At some point in my code, I want the cube to rotate without the user knowing.
Face 1 should still point toward +X.
Face -1 should still point toward -X.
But :
Face 2 should point toward +Z.
Face -2 should point toward -Z.
Face 3 should point toward -Y.
Face -3 should point toward +Y.
Ok?
But I don't want the user to notice this rotation.
So I wanted to rotate the camera at the exact same time in order to hide the fact that the cube rotated.
What I tried:
when I want to rotate X :
cube.rotateX(direction * Math.PI / 2);
camera.position.set(camera.position.x, direction * (-camera.position.z), direction * camera.position.y);
camera.lookAt(new THREE.Vector3(0, 0, 0));
and when I want to rotate Y :
cube.rotateY(-direction * Math.PI / 2);
camera.position.set((-direction) * camera.position.z, camera.position.y, -direction * (-camera.position.x));
camera.lookAt(new THREE.Vector3(0, 0, 0));
Sadly, although it works for the Y rotation, it does not work for the X rotation, because the camera.up will fuck it up and make it look like there was a rotation around the Y axis.
How should I do ?

Try creating a THREE.Group and add everything in your current scene to it (your cube, camera, lights, etc.). Then rotate the group.
var group = new THREE.Group();
group.add(yourCube);
group.add(yourLight);
group.add(yourCamera);
scene.add(group);
// later...
group.rotateN(90 * Math.PI / 180); // whatever rotation function you choose to use
Anything you add to the group from this point on will use the group's coordinate system. Anything added to the scene will continue to use the standard world coordinate system.
If you rotate the group again, anything inside the group will rotate along with it, but anything in the scene will remain in place.

Related

ThreeJS: How to move the camera to the left or right independent of its rotation?

I have a ThreeJS set up where the camera can move through a 3D world and while moving it will change its lookAt multiple times. So let's assume that camera.getWorldDirection() will always be more or less random.
Now I need the camera to move exactly left / right / up / down relative to camera.getWorldDirection().
You can't just use something like camera.position.x += 1 because that only applies for a world direction of Vector3(0, 0, -1). If the world direction changes to e.g. (1, -1, 0), moving the camera to the right does require changes in the X and the Z axis.
I had a look at quaternions and 4D matrices but I can't get my monkeybrain around them. Would be really nice if someone could help me out.
Here is a demo: https://normanwink.com/demo/room/
I found the answer here in a non-accepted answer.
You gotta use camera.translateX() and similar functions to transform its local position. That way you can always manipulate camera.position to move it around and have the translate functions to add offsets relative to the cameras viewing angle.

Three.js: smooth camera lerping around an origin point

I'm working on a three.js scene which renders a cube at the centre of two lines pointing north, east, south and west. I'm using three OrbitControls for interaction and some custom code (see link below) to smoothly lerp the camera around an origin point to predefined positions (N, E, S, W and top).
This is working well, except for a few cases:
Lerp from north to south by clicking the "North" button then "South" button (same issue for east to west). Lerping between vector A and B fails, resulting in the camera just jumping to vector B.
Lerp from a custom rotation e.g. NW to the top down view by clicking the "Top" button. The camera lerps correctly to the vector on the y axis, but since it's rotation isn't being controlled, it snaps to the final camera rotation when the lerping is done.
Is there a better way to handle this smooth transition of a camera around an origin point on a circular path from a current vector to a target vector? Which also works for cases 1 and 2 above.
Here's a link to my CodePen three.js scene so far. Upon clicking a position button, I store the target vector and use the following line to lerp towards the target
camera.position.lerp(cameraTarget, cameraLerpAlpha);
lerp is not sure how to orbitally rotate around that center point. For a quick fix, slightly offset position in lines 4-8 (or when the animation starts) to give it a direction to send it off on:
//notice the 0.1s
n: new THREE.Vector3(0, 0.1, -5),
e: new THREE.Vector3(5, 0.1, 0),
s: new THREE.Vector3(0, 0, 5),
w: new THREE.Vector3(-5, 0, 0),
top: new THREE.Vector3(0, 5, 0.1)
But really you need to look at this answer and use a quaternion slerp rather than lerp if you want it to not be locked by distance to the center point: threejs: smoothly rotate camera towards an object

Rotating on multiple axis with three.js

I'm experimenting with three.js and the deviceorientation event. I'm rotating a cube with my phone's accelerometer, using the technique used in the THREE.DeviceOrientationState plugin. Basically the coordinates from the deviceorientation event angles are converted to radians and applied to a meshes' rotation coordinates (mesh.rotation.x, etc). Pretty basic.
This technique works fine as long as the phone is not rotated more than 90 degrees, but once it hits 90 degrees the rotation get messed up and the cube basically "flips". Not sure how else to describe it. Also, rotation works perfectly when rotating on only one axis, but as soon as two or more axis are involved and the phone is rotated more than 90 degrees we have problems.
Basically I need to know how to combine more than one rotation angle so that the cube rotates with the phone no matter how much the phone is rotated. The cube should always mimic the rotation of the phone. (I know, it's a bit weird to do that since you can't see the phone screen when it has been rotated so much, but bear with me, I have a plan.)
I thought maybe I was hitting gimbal lock, so tried using quaternions, but I get the same results. To be honest, I'm a little embarrassed to be asking this question. It has been a while since I did any 3D programming, but I feel like I should know how to do this.
Here's some example code. What else do I need to do to combine the rotation angles?
$(window).on('deviceorientation', function(e) {
var x = (!e.originalEvent.beta ? 0 : e.originalEvent.beta) * Math.PI / 180;
var y = (!e.originalEvent.gamma ? 0 : e.originalEvent.gamma) * Math.PI / 180;
var z = (!e.originalEvent.alpha ? 0 : (e.originalEvent.alpha - 180)) * Math.PI / 180;
cube.rotation.x = x;
cube.rotation.y = y;
cube.rotation.z = z;
});
UPDATE: Here is a jsfiddle that illustrates the issue. It has been modified to use the DeviceOrientationControls feature, which is now included in three.js. You'll see that the problem persists. Basically I need the cube to mimic the orientation of the phone exactly, no matter how much I turn the phone.
UPDATE 2: I changed the shape in the above jsfiddle from a cube to a 3d rectangle that is in the shape of a phone. I think it's easier to see what's happening with a rectangle than a cube.

Camera rotation around one axis of the scene TrackBallControls.js

I am using r59 of the three.js lib. Based on the stl loader example i am trying to rotate the camera around one axis of the scene. I use TrackBallControls to interface my scene with the mouse.
When i move the mouse i want the scene to rotate with the objects around the origin z-axis. But i can't manage to find a way to block the others directions. Is it in the trackball or in the three lib ?
For example rotate arround the green axis but keeping the angle of the angle of the camera.
When i do :
var mouseOnBall = new THREE.Vector3(
( clientX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
0.0,
0.0
);
The camera rotates only around the green axis but it's not really straight as you can see on the screenshot. And i would like to keep the camera on the initial angle. See the second screenshot :
I am unable to find the anwser most of them on the internet are deprecated.
Sincerely
Austriker

Moving sprite in direction of an angle

I'm making an android game in E3roid I'm attempting to rotate the sprite with the analog stick then have the sprite move in the direction that the ship is facing. Here is the code I used the set the angle.
double angleRadians = Math.atan2(sprite.getRealY() - relativeX,sprite.getRealX() - relativeY);
double angleDegrees = Math.toDegrees(angleRadians);
double angle = -1 * angleDegrees;
sprite.rotate((float)angle);
How would I move the sprite in the same direction as the angle?
do I convert the angle back into Radians?
sprite.move(int,int);
Thanks if you help me!
You can think of your angle as the hypotenuse of a right triangle. To move your sprite a certain number of pixels up and right, you need to use geometry to figure out how many pixels that is. sin and cos should do the trick. If you have forgotten your geometry

Categories

Resources