0

I am trying to create a 2D game. Because I am using OpenGL ES I have to plot everything in 3D, but I just fix the z coordinate, which is fine. Now what I want to do is calculate the angle between two vectors (C = player center, P = point just above player, T = touch point) CP and CT so that I can make the player face that direction. I know how to get the angle between 2 vectors, but my problem is getting all the points to exist on the same plane (by translating the T).

I know that T exists on a plane where (0,0) is upper left and UP is actually DOWN (visually). I also know that C and P's UP is actually UP and that any their X and Y is on a completely 3 dimensional different plane to T. I need to get either C and P onto T's plane (which I have tried below) or get T onto C and P's plane. Can anyone help me? I am using the standard OpenGL projection model and I am 0,0,-4 zoomed out of the frustrum (I am looking directly at (0,0,0)). My 2D objects all sit on the plane (0,0,1);

private float getRotation(float touch_x, float touch_y)
{
    //center_x = this.getWidth() / 2;
    //center_y = this.getHeight() / 2;

    float cx, cy, tx, ty, ux, uy;

    cx = (player.x * _renderer.centerx);
    cy = (player.y * -_renderer.centery);

    ux = cx;
    uy = cy+1.0f;

    tx = (touch_x - _renderer.centerx);
    ty = (touch_y - _renderer.centery);

    Log.d(TAG, "center  x: "+cx+"y:"+cy);
    Log.d(TAG, "up      x: "+ux+"y:"+uy);
    Log.d(TAG, "touched x: "+tx+"y:"+ty);

    float P12 = length(cx,cy,tx,ty);
    float P13 = length(cx,cy,ux,uy);
    float P23 = length(tx,ty,ux,uy);

    return (float)Math.toDegrees(Math.acos((P12*P12 + P13*P13 - P23*P23)/2.0 * P12 * P13));
}

Basically I want to know if there is a way I can translate (tx, ty, -4) to (x, y, 1) using the standard view frustum.

I have tried some other things now. In my touch event I am trying to do this:

float[] coords = new float[4];
GLU.gluUnProject(touch_x, touch_y, -4.0f, renderer.model, 0, renderer.project, 0, renderer.view, 0, coords, 0);

Which is throwing an exception I am setting up the model, projection and view in the OnSurfaceChanged of the Renderer object:

    GL11 gl11 = (GL11)gl;

    model = new float[16];
    project = new float[16]; 
    int[] view = new int[4];

    gl11.glGetFloatv(GL10.GL_MODELVIEW, model, 0);
    gl11.glGetFloatv(GL10.GL_PROJECTION, project, 0);
    gl11.glGetIntegerv(GL11.GL_VIEWPORT, view, 0);
Quintin Balsdon
  • 5,484
  • 10
  • 54
  • 95
  • possible duplicate of [Handling touch events in a 3D "scene" or Screen to 3D coordinates](http://stackoverflow.com/questions/8014165/handling-touch-events-in-a-3d-scene-or-screen-to-3d-coordinates) – mbeckish Mar 01 '13 at 15:28
  • I have also been looking here and not found a reason why my code should not be working: http://stackoverflow.com/questions/8010971/how-to-move-a-opengl-square-with-the-finger – Quintin Balsdon Mar 01 '13 at 20:11

2 Answers2

1

I have several textbooks on openGL and after dusting one off I found that the term for what I want to do is called picking. Once I knew what I was asking, I found a lot of good web sites and references:

The list is almost innumerable. There are 700 ways to do this, and none of them worked for me. Ultimately I have decided to go back to basics and do a thorough OpenGL|ES learning stint, to which effect I have bought the book here: http://www.amazon.com/Graphics-Programming-Android-Programmer-ebook/dp/B0070D83W2/ref=sr_1_2?s=digital-text&ie=UTF8&qid=1362250733&sr=1-2&keywords=opengl+es+2.0+android

One thing I have already learnt is that I was most definitely using the wrong type of projection. I should not use full 3D for a 2D game. In order to do picking in a full 3D environment I would have to cast a ray from the screen point onto the surface of the 3D plane where the game was taking place. In addition to being a horrendous waste of resources (raycasting per click), there were other tell-tales. I would render my player with a circle encompassing her, and as I moved her, the circle would go off center of the player. This is due to the full 3D environment rendered on a 2D plane. It just will not produce a professional result. I need to use an orthographic projection.

Community
  • 1
  • 1
Quintin Balsdon
  • 5,484
  • 10
  • 54
  • 95
  • This actually seems to be the best: http://stackoverflow.com/questions/11343721/cant-find-suitable-example-for-android-2d-opengl-sprite-class-wich-does-not-use – Quintin Balsdon Mar 03 '13 at 19:51
0

I think you're trying to do too much all at once. I can understand each sentence of your question separately; but strung all together, it's very confusing.

For the exceptions, you probably need to pass identity matrices instead of zero matrices to get a basic 1-to-1 projection.

Then I'd suggest that you scale the y dimension by -1 so all the UPs and DOWNs match at least.

I hope this helps, because I'm not 100% sure what you're trying to do. Particularly, " translate (tx, ty, -4) to (x, y, 1) using the standard view frustum" doesn't make sense to me. You can translate with a translation matrix. You can clip to a view frustum, or project an object from the frustum to a plane (usually the view plane). But if all your Zs are constant, you can just discard them right? So, assuming x=tx and y=ty, then tz += 5?

luser droog
  • 18,988
  • 3
  • 53
  • 105