ARCore: random object rotation on vertical plane - java

I managed to position a 3D model on a vertical plane (using ARCore 1.4); it works well enough but the model is not in landscape starting position; instead, it starts randomly placed rotated, clockwise or counterclockwise (random degrees).
Is there a way to force it to start horizontally?

Fixed.
I've passed the pose object of the plane to the createAnchor method, in my onTapArPlaneListener.
Like this:
anchor = mySession.createAnchor(plane.getCenterPose());

Related

Libgdx Coordinate System Origin(0,0), not at bottom left of screen

I am working on a program to visualize an n-body particle simulation. To do this I have created a camera which is used to project particle positions unto the screen. Then, using a spritebatch these particles are rendered in the correct positions. However, for this to work, the origin of the coordinate system must be located at the bottom left of the screen. This is often not the case and instead the origin is located about a fourth of the screen up and to the left in all cases, and this changes when resizing the screen.
How do I guarantee the coordinate system origin is always at the bottom left of the screen, instead of elevated by a few hundred pixels in either axis?
Thank you.
If you decided to use sprite you should stick with proposed workflow and draw them with:
sprite.draw(batch);
I mean, what's the purpose using sprites if you are getting textures and drawing them?
When you draw a texture to screen at position (0,0) it means that it's bottom left corner will be at screen bottom left corner. That' is sprite's "hot-spot" or "origin" is at it's left bottom corner by default.
But you can change that with setOrigin method:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Sprite.html#setOrigin-float-float-
That is, origin is kinda "center" of the sprite, so i.e. if it rotates it will rotate around that spot. Also when you draw sprite at some coordinates sprites origin will be exactly at those coordinates. That way you don't have to adjust sprite drawing position.
Check on that page what methods you have for sprite class...
I fixed my problem. Instead of using:
sprite.draw(batch);
I used:
batch.setColor(color);
batch.draw(sprite.getTexture(),sprite.getX(),sprite.getY(),sprite.getWidth()*sprite.getScaleX(),sprite.getHeight()*sprite.getScaleY());
I do not know why this worked.

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

Implementing trapezoidal sprites in LibGDX

I'm trying to create a procedural animation engine for a simple 2D game, that would let me create nice looking animations out of a small number of images (similar to this approach, but for 2D: http://www.gdcvault.com/play/1020583/Animation-Bootcamp-An-Indie-Approach)
At the moment I have keyframes which hold data for different animation objects, the keyframes are arrays of floats representing the following:
translateX, translateY, scaleX, scaleY, rotation (degrees)
I'd like to add skewX, skewY, taperTop, and taperBottom to this list, but I'm having trouble properly rendering them.
This was my attempt at implementing a taper to the top of the sprite to give it a trapezoid shape:
float[] vert = sprite.getVertices();
vert[5] += 20; // top-left vertex x co-ordinate
vert[10] -= 20; // top-right vertex x co-ordinate
batch.draw(texture, vert, 0, vert.length);
Unfortunately this is producing some weird texture morphing.
I had a bit of a Google and a look around StackOverflow and found this, which appears to be the problem I'm having:
http://www.xyzw.us/~cass/qcoord/
However I don't understand the maths behind it (what are s, t, r and q?).
Can someone explain it a bit simpler?
Basically, the less a quad resembles a rectangle, the worse the appearance due to the effect of linearly interpolating the texture coordinates across the shape. The two triangles that make up the quad are stretched to different sizes, so linear interpolation make the seam very noticeable.
The texture coordinates of each vertex are linearly interpolated for each fragment that the fragment shader processes. Texture coordinates typically are stored with the size of the object already divided out, so the coordinates are in the range of 0-1, corresponding with the edges of the texture (and values outside this range are clamped or wrapped around). This is also typically how any 3D modeling program exports meshes.
With a trapezoid, we can limit the distortion by pre-multiplying the texture coordinates by the width and then post-dividing the width out of the texture coordinates after linear interpolation. This is like curving the diagonal between the two triangles such that its slope is more horizontal at the corner that is on the wider side of the trapezoid. Here's an image that helps illustrate it.
Texture coordinates are usually expressed as a 2D vector with components U and V, also known as S and T. But if you want to divide the size out of the components, you need one more component that you are going to divide by after interpolation, and this is called the Q component. (The P component would be used as the third position in the texture if you were looking up something in a 3D texture instead of a 2D texture).
Now here comes the hard part... libgdx's SpriteBatch doesn't support the extra vertex attribute necessary for the Q component. So you can either clone SpriteBatch and carefully go through and modify it to have an extra component in the texCoord attribute, or you can try to re-purpose the existing color attribute, although it's stored as an unsigned byte.
Regardless, you will need pre-width-divided texture coordinates. One way to simplify this is to, instead of using the actual size of the quad for the four vertices, get the ratio of the top and bottom widths of the trapezoid, so we can treat the top parts as width of 1 and therefore leave them alone.
float bottomWidth = taperBottom / taperTop;
Then you need to modify the TextureRegion's existing texture coordinates to pre-multiply them by the widths. We can leave the vertices on the top side of the trapezoid alone because of the above simplification, but the U and V coordinates of the two narrow-side vertices need to be multiplied by bottomWidth. You would need to recalculate them and put them into your vertex array every time you change the TextureRegion or one of the taper values.
In the vertex shader, you would need to pass the extra Q component to the fragment shader. In the fragment shader, we normally look up our texture color using the size-divided texture coordinates like this:
vec4 textureColor = texture2D(u_texture, v_texCoords);
but in our case we still need to divide by that Q component:
vec4 textureColor = texture2D(u_texture, v_texCoords.st / v_texCoords.q);
However, this causes a dependent texture read because we are modifying a vector before it is passed into the texture function. GLSL provides a function that automatically does the above (and I assume does not cause a dependent texture read):
vec4 textureColor = texture2DProj(u_texture, v_texCoords); //first two components automatically divided by last component

How to rotate a single shape in 3d space in opengl?

so I'm pretty new with opengl and creating 3d shapes. So for my example I have two squares, one with a height/width 2 with the center at the origin coordinate (0,0,-10), and one that is to the far left side of the window. I am trying to rotate the square that lies in the origin along the x-z plane without rotating the square that is located to the far left side of the screen. My approach to this was to save each xyz coordinate of the center square to a variable, and creating a method that uses the behavior of cos(theta) to rotate the square along the x-z plane. My code works, but I assume this is a horrible approach as there must be some more efficient method that is already created that can do the same functionality. I looked at glRotatef(), but from what I understood this only rotates my camera view which in the end would rotate both the middle square and the far left square whereas I only want to rotate the middle square. Is there some other method that already exists that can easily rotate a single 2d shape in 3d space?
In case its relevant, I have included the rotating code I made myself for the middle square: (btw the blue class is just some class I made that has the squares coordinates and the circle degree for cos(theta))
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
blue.setCircle(blue.getCircle()+1f);//getCircle is initially zero and gets incremented by 1 for everytime the program loops with the user holding the left button.
blue.setXfrontTR((float)Math.cos(Math.toRadians(blue.getCircle())));//Changing top-right x coordinate of the middle square
blue.setZfrontTR(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+270f)))); //Changing top-right z coordinate of the middle square.
blue.setXfrontTL((float)Math.cos(Math.toRadians(blue.getCircle()+180f)));
blue.setZfrontTL(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+90f))));//Changing top-left x,z coordinates
blue.setXfrontBL((float)Math.cos(Math.toRadians(blue.getCircle()+180f)));
blue.setZfrontBL(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+90f))));//Changing bottom-left x,z coordinates
blue.setXfrontBR((float)Math.cos(Math.toRadians(blue.getCircle())));
blue.setZfrontBR(-10f+ ((float)Math.cos(Math.toRadians(blue.getCircle()+270f))));//Changing bottom-right x-z coordinates
}
If you give each object that requires independent movement a model-view matrix you can achieve this. The other option to quickly draw/move a few independent objects is to:
for each object:
pushMatrix()
draw object
popMatrix()
while in the modelview matrix...
The method of drawing depends greatly on the OpenGL version you're coding to but the above will work for simple drawing. I'm not an expert on OpenGL / 3D programming so, if you wait a bit you may hear(see) better wisdom than what I offer :)

libGDX spiriteBatch.draw() not positioning at the right place

Here is a sample code that is not correctly functioning for me, am I doing something wrong?
textureCharacter = new Texture(Gdx.files.internal("data/character1.png"));
if (Gdx.input.isTouched()) {
spriteBatch.draw(textureCharacter, Gdx.input.getX(), Gdx.input.getY());
}
When I touch the the SpiriteBatch at the location X=5 and Y=5 (for example) it draws me the texture at X 5 but Y is the Gdx.graphics.getHeight() - 5px ??? By moving the input Y down, the texture moves up...
Gdx.input.getX() and Gdx.input.getY() are returning the values: X=5, Y=5
What I'm trying to do is just move the texture to the input positions I'm touching/moving.
Screen coordinates are not necessarily the same as model-space coordinates. What does your camera definition look like? (Since that defines the mapping of model space to the screen.) The Gdx.intput.getX() call returns a point in screen space.
The Y-axis (by default) points in opposite directions on the screen and in GL space. (grows down from the top of the screen in screen coordinates, and grows up towards the top of the screen in GL coords). You can either fix your camera to match the screen coordinates or map your touch coordinates into GL coordinates.
See the call to camera.unproject() in:
https://code.google.com/p/libgdx/source/browse/trunk/tests/gdx-tests/src/com/badlogic/gdx/tests/examples/MoveSpriteExample.java

Categories

Resources