The short story: I am trying to use THREE.TrackballControls to move the camera, but the (upside-down) x-z plane is where the x-y plane should be. Can anyone help?
The long story: I've been trying to add device orientation controls to a project. I have already used the THREE.TrackballControls to move the camera when mouse and touch are being used, and the direction the camera points feeds into other functionality. I am using v69 of three.js.
So, I have been looking into using THREE.DeviceOrientationControls to enable device orientation. Specifically, what I'm after is for rotation to be in the x-y plane when the device is upright in front of me and I turn around. Or in other words, when the device is face up on the table it is looking in the -ve z-direction, and when upside down it it looking in the +ve z-direction. Sounds fairly straightforward, right?
There are plenty of examples around to follow, but I seem to be stuck with axes incorrectly orientated, i.e. what should be my x-y plane is coming out as the x-z plane, but upside-down. I created a test page based on an example with a BoxGeometry cube I found, and then added red, yellow and blue spheres to the middle of the faces that corresponded to the +ve x-, y-, and z-directions respectively, and then pale versions of the same coloured spheres for the corresponding -ve directions. Testing this on an iPad confirmed that the scene axes and the real world axes were not lining up.
I have spent a bit of time trying to get to grips with how this Object works, and the main sticking point is in the function returned by setObjectQuaternion() which does the tricky bit:
...
return function (quaternion, alpha, beta, gamma, orient) {
euler.set(beta, alpha, -gamma, 'YXZ'); // 'ZXY' for the device, but 'YXZ' for us
quaternion.setFromEuler(euler); // orient the device
quaternion.multiply(q1); // camera looks out the back of the device, not the top
quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation
}
...
where q1 is quaternion for a -pi/2 rotation around the x-axis, and zee is a unit z-axis vector.
I set up a jsfiddle here to help me debug this, but it wasn't rendering correctly on the iPad itself, so I had to add in some faking of orientation events, and plenty of logging, and continue on a normal desktop + console. This jsfiddle goes through each of the 6 basic orientations and sees whether the camera is looking in the direction I expect.
(Initially it would seem that a pi/2 rotation around the x-axis is what is required, but removing the quaternion.multiply(q1) doesn't fix it - I haven't even started looking at non-zero screen orientations yet.)
Ultimately, I'd like to make this more like the TrackballControls/OrbitControls with a target point that the camera always looks at (unless panned) and rotates around, once I've figured this "simple" stuff out.
Anybody have any ideas how I can orientate my camera properly?
Related
I have been experimenting with three.js for a website I'm making.
I came across the spline curve solution in order to make a camera follow a cinematic path, and linked it to the drei's scroll component in order to make the camera follow a cinematic path relative to the current scroll of the page.
The problem that I'm facing is that I want the camera to have smoothed out stop points, I have already successfully added stop points without the smoothing, by using the range function from the offset object from the Drei's scroll component and it works just fine.
I'm looking for a way to slow down the camera before it stops. Already tried to change the offset.range value (which is linear) to an exponential value, this partially works it slows down the camera movement until half of the function and after coming to a complete stop it turns around and goes in reverse in the path.
I'm using a Perspective Camera for my top down Three.js game, but it curves a bit too much because it's designed to be used as "first person view". Is there a way to adjust how much objects bend/curve in the frustum from the sides?
Essentially, I would like something like a mix of a Perspective Camera and an Orthographic Camera
E.g -- The walls of the buildings should be less visible from a certain distance
You can adjust the camera FOV.
https://threejs.org/docs/?q=persp#api/en/cameras/PerspectiveCamera
Made a simple Pen here:
https://codepen.io/cdeep/pen/eYEOqrz
camera.fov = 30;
camera.updateProjectionMatrix ();
The lesser the FOV, the more flatter things look.
Please note that you'll need to position the camera farther away at lower FOVs to ensure the contents fit inside the view which also requires you to increase the camera's far property so things don't get cut out
I've been working for some time on making a 3D first person camera in p5.js for games and random projects, but I've been having some trouble.
For some time now I've been using a single y-rotation matrix with my projects to allow the player to look around, but I've felt like having an upgrade recently, so I decided to use x and y rotation matrices for my camera code. I was able to botch together a system that kind of worked by dividing both calculated z values, but there were some issues, not to mention that's not how rotation matrices work. I recently tried doing a proper implementation, but I've come across some issues.
I've been using this: camera(0, 0, 0, -200*sin(rot.y), -200*sin(rot.x), (200*cos(rot.x)) + (200*cos(rot.y)), 0, 1, 0); as my test camera code, which in theory would work, but in an actual setting, it doesn't for some reason, as you can see here. Right now if you look around too far it will randomly spaz out and mess up the way you're looking.
I also can confirm that I am using the correct formulas as here. I used the (almost) exact same code for calculating the values, and it looks completely fine.
Is there any weird trick to using the p5.js camera or is this some error that needs to be fixed?
You actually don't have the correct formulas. The example you showed uses orbitControl(), not camera. It also doesn't have two different angles it's rotating through.
The middle 3 coordinates of camera() define the point toward which the camera is pointing. That means that you want that point to move the same way you want the focus of the camera to move. It might help to draw a box at that point like this (in your original):
push();
translate(-200*sin(rot.y), -200*sin(rot.x), (200*cos(rot.x)) + (200*cos(rot.y)));
box(50);
pop();
You'll notice that the box is not always the same distance from the camera. It stays on a torus whose major and minor radii are both 200. What you want is a sphere with radius 200 (really it can have any radius).
The way you define these three coordinates depends on how you want the user's interactions to be. Here's one way:
camera(0, 0, 0,
cos(rot.x) * cos(rot.y),
cos(rot.x) * sin(rot.y),
sin(rot.x),
0, 0, 1);
This points the camera based on latitude and longitude, with the north pole on the positive Z axis. Moving the mouse right and left affects the longitude, and up and down affects the latitude.
I'm trying to build a motorbike game in html5 canvas with javascript.
Right now I have a wheel and a simple gravity which increases the position from the top of the canvas until the wheel hits the bottom of the canvas. When I start the game, the wheel just drops to the bottom of the canvas.
I want to create a curved ground for the wheel to ride on. The problem is that I don't know how to calculate if the wheel hits this ground.
Here is a illustration. I want the wheel to drop until it hits the curved ground, and if I'm moving the wheel, it needs to follow the shape's edge.
image http://i.minus.com/iFvy1dbnouvy6.png
I don't want to use any libraries or engines, only javascript and html5. Do you have any ideas or solutions?
Similar to the other answer, you can simply have an if statement that says
if tire.y < line(tire.x) then tire.y = line(tire.x) - 1
the line function can just be an array or some formula that will contain the y value of the line when given any x-value.
In order to detect when the wheel hits the ground, you should have the coordinates of the ground boundary (e.g.: a polyline) and the wheel's ray and center position.
You detect collision by checking that your wheel y coordinate (cener + ray) is below the y coordinate of your polyline at certain x(s). You should segment your polyline in a resonable way, by carefully selecting your endpoints.
Probably there are other ways to accomplish this task, but this is the first which I came out.
Here is the solution which you're looking for Collision Detection (elastic)..
.--------------------------------------------------------------------------------------------.
Here's a simple & Good tutorial for learning physics especially for Game Developers
What I want to achieve is a camera rotation like http://www.keithclark.co.uk/labs/3dcss/demo/ . It's not perfect and sometimes the camera breaks, but that's the idea.
I like the rotation to be similar like a human view, but I only managed to obtain a rotation across a certain point. This is an example of what I obtained http://jsfiddle.net/gaAXk/3/.
As i said before, i would like a human like behaviour.
I also tried with -webkit-transform-origin but with no better result.
Any help/suggestion will be highly appreciated.
The problem here is the following:
To give a human-like behavior, when the point of view moves, you should calculate the new positions on the x/y/z axis for the objects (not just the rotation angle in case of a rotation, for instance).
CSS transform should work in the follwing way, we give a perspective, for example of 800px to a scene. Then the objects will be visible with a Z position up to 800px, if the Z position is, for example 1000px, it will be behind our point of view, so we won't be able to see the element.
That said, after a rotation you should calculate the new position for the items based on our new point of view.
To be clearer I've updated your example with much simpler code (it only supports rotation and there's just one image): http://jsfiddle.net/gaAXk/12/
The perspective in the example is 800px.
The image is initially placed at x=0px, y=0px, z=0px. So it will be visible in front of us at a "distance" of 800px.
When we rotate the point of view, the element should move along a circumference around the point of view, so the x,z positions and the rotation angle of the element, needs to be updated.
The element in the example moves along a circumference with 800px radius (the calculatePos() function does the trick).
The same calculation should be updated if we change position (if the point of view gets closer to some objects, and further from others).
This isn't so trivial. If anyone has better solutions (I'm not a 3D expert), I will be glad to hear some.