Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've spent more time than I should trying to get my ray picking program working. I'm pretty convinced my math is solid with respect to line plane intersection, but I believe the problem lies with the changing of the mouse screen touch into 3D world space.

Heres my code:

    public void passTouchEvents(MotionEvent e){


        int[] viewport = {0,0,viewportWidth,viewportHeight};
        float x = e.getX(), y = viewportHeight - e.getY();

        float[] pos1 = new float[4];
        float[] pos2 = new float[4];
        GLU.gluUnProject(   x, y, 0.0f,
                            mViewMatrix, 0,
                            mProjectionMatrix, 0,
                            viewport, 0,
                            pos1, 0);


        GLU.gluUnProject(   x, y, 1.0f,
                            mViewMatrix, 0,
                            mProjectionMatrix, 0,
                            viewport, 0,
                            pos2, 0);
    }

Just as a reference I've tried transforming the coordinates 0,0,0 and got an offset. It would be appreciated if you would answer using OpenGL ES 2.0 code.

share|improve this question
1  
Since GLU isn't part of OpenGLES, is this GLU implementation a port? Is gluUnProject implemented in it? –  kaoD Mar 28 '12 at 2:33
    
i'm using the android GLU library and what evers in that. You'll have to forgive my ignorance I'm still new to opengl on android. –  secheung Mar 28 '12 at 3:26
2  
You don't mention what the problem is... –  Byte56 Mar 28 '12 at 20:59
    
Sorry about that. My problem is the converted coordinates don't seem to be "unprojecting" the coordinates into world space. Is there anything wrong with my code or is there something i'm not getting? –  secheung Mar 28 '12 at 23:38
    
The code looks about right... I suspect the matrices are off. Are you using the MODELVIEW_MATRIX for mViewMatrix? Here is a working piece of code using JOGL if it helps: pastebin.com/8a3mKkAq –  Danik May 23 '12 at 19:29
add comment

1 Answer

up vote 2 down vote accepted

The GLU library was made with 1.1, but the gluUnProject can still be used in 2.0 as long as you have the correct values. The 4th parameter should be the multiplied model view matrix, not just the model matrix or just the view matrix. Also, the calculated pos1 and pos2 values have to be converted from 4D vectors to 3D vectors by dividing them by their w component. According to this: http://forums.create.msdn.com/forums/p/10940/70238.aspx.
Here's how I did it for Android:

public void singleTouch(float x, float y)
{
    float[] nearPos = new float[4];
    float[] farPos = new float[4];
    PointF touchPoint;

    boolean unprojectedNear = (GLU.gluUnProject(x, y, 0,
        floorViewDrawable.getMvMatrix(), 0, projectionMatrix, 0,
        viewport, 0, nearPos, 0) == GLES10.GL_TRUE);
    boolean unprojectedFar = (GLU.gluUnProject(x, y, 1,
        floorViewDrawable.getMvMatrix(), 0, projectionMatrix, 0,
        viewport, 0, farPos, 0) == GLES10.GL_TRUE);

    if (unprojectedNear && unprojectedFar)
    {
        // To convert the transformed 4D vector to 3D, you must divide
        // it by the W component
        nearPos = convertTo3d(nearPos);
        farPos = convertTo3d(farPos);

        // Use the near and far instead of the assumed camera position
        float floorViewX = (((farPos[0] - nearPos[0]) / (perspectiveFar - perspectiveNear)) * nearPos[2]) + nearPos[0];
        float floorViewY = ((((farPos[1] - nearPos[1]) / (perspectiveFar - perspectiveNear)) * nearPos[2])  + nearPos[1]) + (2f * positionY);

        touchPoint = new PointF(floorViewX, floorViewY);

        if (floorViewDrawable.getArea()
            .contains(touchPoint.x, touchPoint.y))
        {
            floorViewPoint = new PointF(nearPos[0], nearPos[1]);
            Log.e(HostessMobileApp.TAG, "floorViewTouched");
        }
    }
}

private float[] convertTo3d(float[] vector) {
    float[] result = new float[4];

    for (int index = 0; index < vector.length; index++) {
        result[index] = vector[index] / vector[3];
    }

    return result;
}

Here's a resource for explaining gluUnproject if anybody needs it. http://myweb.lmu.edu/dondi/share/cg/unproject-explained.pdf

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.