Rotation in OpenGl ES to place objects then rotate the world - java

I am developing an augmented reality application for android and trying to use openGl to place cubes at locations in the world. My current method can be seen in the code below:
for(Marker ma: ARData.getMarkerlist().values()) {
Log.d("populating", "");
gl.glPushMatrix();
Location maLoc = new Location("loc");
maLoc.setLatitude(ma.lat);
maLoc.setLongitude(ma.lng);
maLoc.setAltitude(ma.alt);
float distance = currentLoc.distanceTo(maLoc);
float bearing = currentLoc.bearingTo(maLoc);
Log.d("distance", String.valueOf(distance));
Log.d("bearing", String.valueOf(bearing));
gl.glRotatef(bearing,0,0,1);
gl.glTranslatef(0,0,-distance);
ma.cube.draw(gl);
gl.glPopMatrix();
}
gl.glRotatef(y, 0, 1, 0);
gl.glRotatef(x, 1, 0, 0);`
Where y is yaw and x is the pitch. currently I am getting a single cube on the screen at a 45 degree angle someway in the distance. It looks like I am getting sensible bearing and distance values. Could it have something to do with the phones orientation? If you need more code let me know.
EDIT: I updated bearing rotation to gl.glRotatef(bearing,0,1,0); I am now getting my cubes mapped horizontally along the screen at different depths. Still no movement using heading and pitch but #Mirkules has identified some reasons why that might be.
EDIT 2: I am now attempting to place the cubes by rotating the matrix by the difference in angle between heading and bearing to a marker. However, all I get is a sort of jittering where the cubes appear to be rendered in a new position and then jump back to there old position. Code as above except for the following:
float angleDiff = bearing - y;
gl.glRotatef((angleDiff),0,1,0);
gl.glTranslatef(0,0,-distance);
bearing and y are both normalised to a 0 - 360 scale. Also, I moveed my "camera rotation" to above the code where I set the markers.
EDIT 3: I have heading working now using, float angleDiff = (bearing + y)/2;. However, I cant seem to get pitch working. I have attempted to use gl.glRotatef(-x,1,0,0); but that doesn't seem to work.

It's tricky to tell exactly what you're trying to do here, but there are a few things that stick out as potential problems.
Firstly, your final two rotations don't seem to actually apply to anything. If these are supposed to represent a movement of the world or camera (which mostly amounts to much the same thing) then they need to happen before drawing anything.
Then your rotations themselves perhaps won't entirely do what you intend.
Your cube is rotated around the Z axis. The usual convention in GL is for the camera to look down the Z axis, with the Y axis being considered 'up'. You can naturally interpret axes however you like, but a rotation around 'Z' would not typically be 'bearing', but 'roll'. 'Bearing' to me would be analogous to 'yaw'.
As you translate along the Z axis, I assume you are trying to position the object by rotating and translating, but obviously if the rotation is around the same axis as you translate along, it won't actually alter the position of the cube - it will always just be directly in front of the camera, spinning on its axis.
I'm not really clear on why you're trying to position the cube like that when it seems like you start off with a more specific location. You could probably directly construct a more appropriate matrix.
Finally, your camera/world rotation is two concatenated rotations around Y and X. You call these pitch and roll, but typically using euler angles for a camera rotation does not result in an intuitive result where terms like pitch and roll make complete sense. It is common to maintain an orientation and apply individual rotations to that in order to update it, rather than attempting to update several dependent rotations.
So yes, I would expect that this code, in the absence of other matrix operations, would likely result in drawing one or more cubes straight ahead which are simply rotated by some angle around the view direction.

Related

Java - How to create a 3D vector based on the rotation of a camera

I am trying to create a vector based on the rotation of my camera, for example if the camera looked straight forward it would be <0, 0, -1> (Note: The axes are based on the opengl ones) or if the camera was looking to the right and a bit up it would be <0.5, 0.5, 0>
I am using the lwjgl library so joml is avaliable. But if its easier just creating x,y,z float's is fine.
Note: The camera only uses x and y rotation as z rotation isn't needed and you cant just construct a vector purely based on those and make z rotation 0, it doesn't work.
In layman's terminology I want a vector that if you added it to the position of a player it would move in the direction that the camera is facing.
Edit:
Correct locations in joml are:
x=m02
y=m12
z=m22
Your forward direction should just be the z axis (3rd column) of your camera matrix. Depending on the API you are using the "camera matrix" might be it's inverse, in that case take the 3rd row.

Calculating coordinates of an oblique aerial image

I am using a GoPro HERO 4 on a drone to capture images that need to be georeferenced. Ideally I need coordinates of the captured image's corners relative to the drone.
I have the camera's:
Altitude
Horizontal and vertical field of view
Rotation in all 3 axes
I have found a couple of solutions but I can't quite translate them for my purposes. The closest one I found is here https://photo.stackexchange.com/questions/56596/how-do-i-calculate-the-ground-footprint-of-an-aerial-camera but I can't figure out how and if it's possible for me to use it. Particularly when I have to take both pitch and roll into account.
Thanks for any help I get.
Edit: I code my software in Java.
If you have rotations in all three axes then you can use these matrices - http://planning.cs.uiuc.edu/node102.html - to construct a full (3x3) rotation matrix for your camera.
Assuming that, when the rotation matrix is an identity (i.e. in the camera's frame) you have defined the camera's axes to be:
X axis for front
Y for side (left)
Z for up
In the camera frame, the rays have directions:
Calculate these directions and rotate them using the matrix to get the real-world axes. Use the camera's real world coordinate as the source.
To calculate the points on the ground: https://www.cs.princeton.edu/courses/archive/fall00/cs426/lectures/raycast/sld017.htm

Android translated canvas collision of rectangles

im trying do develop a Zelda like game. So far i am using bitmaps and everything runs smooth. At this point the camera of the hero is fixed, meaning, that he can be anywhere on the screen.
The problem with that is scaling. Supporting every device and keeping every in perfect sized rects doesnt seem to be that easy :D
To prevent that i need a moving camera. Than i can scale everything to be equally sized on every device. The hero would than be in the middle of the screen for the first step.
The working solution for that is
xCam += hero.moveX;
yCam += hero.moveY;
canvas.translate(xCam,yCam);
drawRoom();
canvas.restore();
drawHero();
I do it like this, because i dont wand to rearrange every tile in the game. I guess that could be too much processing on some devices. As i said, this works just fine. the hero is in the middle of the screen, and the whole room is moving.
But the problem is collision detection.
Here a quick example:
wall.rect.intersects(hero.rect);
Assuming the wall was originally on (0/0) and the hero is on (screenWitdh/2 / screenHeight/2) they should collide on some point.
The problem is, that the x and y of the wall.rect never change. They are (0/0) at any point of the canvas translation, so they can never collide.
I know, that I can work with canvas.getClipBounds() and then use the coordinates of the returned rect to change every tile, but as I mentioned above, I am trying to avoid that plus, the returned rect only works with int values, and not float.
Do you guys know any solution for that problem, or has anyone ever fixed something like this?
Looking forward to your answers!
You can separate your model logic and view logic. Suppose your development dimension for the window is WxH. In this case if your sprite in the model is 100x100 and placed at 0,0, it will cover area from 0,0 to 100, 100. Let's add next sprite (same 100x100 dimension) at 105,0 (basically slightly to the right of the first one), which covers area from 105,0 to 205,100. It is obvious that in the model they are not colliding. Now, as for view if your target device happens to be WxH you just draw the model as it is. If your device has a screen with w = 2*W, h = 2*H, so twice as big in each direction. You just multiply the x and y by w / W and h / H respectively. Therefore we get 2x for x and y, which on screen becomes 1st object - from 0,0 to 200, 200, 2nd object - from 210,0 to 410, 200. As can be seen they are still not colliding. To sum up, separate your game logic from your drawing (rendering) logic.
I think you should have variables holding the player's position on the "map". So you can use this to determine the collision with the non changing wall. It should look something like (depensing on the rest of your code):
canvas.translate(-hero.rect.centerX(), -.rect.centerY());
drawRoom();
canvas.restore();
drawHero();
Generally you should do the calculations in map coordinates, not on screen. For rendering just use the (negative) player position for translation.

Java/LWJGL: Z axis in OpenGL behaving like left-handed coordinate system

Recently, I sought help regarding 3d camera rotations in OpenGL. This answer and the comments that followed helped me greatly, but there is still one major issue: when moving the camera, the motion is often, but not always, in exactly the opposite direction it should be. For instance, when the camera's orientation matrix is the identity, the camera moves perfectly. However, if it is rotated in any direction, its motion on the axis perpendicular to the axis of rotation will have the opposite sign of the intended motion.
With this said, I think I have an idea why this inconsistent behavior is happening:
As we all know, OpenGL uses a Right-Handed coordinate system:
If I understand this diagram correctly, when the camera is oriented at the identity the z axis should point INTO the camera, and z-values should decrease as one moves away from the camera (apparently affirmed here). (coordinates measured in world space).
However, in my program, the Z axis points AWAY from the camera and z values increase as one moves away from the camera. Here is an example:
The camera has moved forward, along what should be the negative z axis but appears to be the positive z axis.
If I am correct in interpreting this behavior as abnormal, it would explain all of my problems with the sign of my camera motion, as the motion that currently appears "correct" would in fact be erroneous and I have consistent signs that I could simply invert to result in correct motion.
So the question is:
Is my Z axis backwards, or is it supposed to be this way?
If it is backwards, why? Judging by multiple discussions on the topic (1, 2, 3), the error is likely to lie where I define my perspective frustum, so I'll put that here:
public static final int P_ZNEAR = 1, P_ZFAR = 500;
public static void perspective()
{
int i = GL11.glGetInteger(GL11.GL_MATRIX_MODE);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
double ymax, xmax;
ymax = P_ZNEAR * Math.tan(FOV / 2);
xmax = ymax * ASPECT_RATIO;
GL11.glFrustum(xmax, -xmax, -ymax, ymax, P_ZNEAR, P_ZFAR);
GL11.glMatrixMode(i);
}

Rotation around a specific point (eg, rotate around 0,0,0)

I've been searching a lot on this problem, but I couldn't really find an answer that would fit.
I need to rotate a cylinder around a given point (eg, 0,0,0), but the pivot of the cylinder is given by default. How do i change that?
I found this topic, and it's quite what I would want to do, but I don't know how to do it with java.
To explain better what I would like to do, I'll show 3 images.(v)
imageshack.us/photo/my-images/259/aintgood.jpg
imageshack.us/photo/my-images/840/whatineed.jpg
imageshack.us/photo/my-images/705/nogoodn.jpg
So, the first image shows my basic problem, the cylinder should be positioned with the end at the center of the sphere, let's say (0,0,0). The user gives two angles. The first one is for a rotX command, the second one for a rotZ one. The pivot of the cylinder is at its center, so, as image 3 shows, even if i translate the cylinder so its end is at the center of the sphere, when it rotates, the whole thing ruins.
Image 2 shows what the cylinder-sphere group should look like, regardless the given angles.
The image is not obtained based on an algorithm, but based on calculus, and mouserotated.
The general procedure for rotation about an arbitrary point P is:
Translate by -P (so P is at (0, 0, 0))
Rotate around the origin
Translate by P (to bring the origin back to the original location of P)
The easiest way to do this is to represent everything in homogeneous coordinates and represent translations and rotations by matrices. Composing the above three transformations (translate-rotate-translate) is done by matrix multiplication. If the rotation is composed of two or more simpler rotations, then the rotation matrix itself is a product of the matrices for the simpler rotations.

Categories

Resources