Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (600)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  3d world mouse coordinates?  (Read 4908 times)
0 Members and 1 Guest are viewing this topic.
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Posted 2006-01-03 19:35:20 »

i have a small problem that i'm stuck on, i'm trying to get the 3d coordinates of the place i click on in a 3d world with the mouse, i have tried a few methods but haven't been able to get any good results

currently i do 

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public void get3dCoord(int mouseX, int mouseY) {
     GLU.gluUnProject( mouseX, mouseY, getZDepthAtOrigin(), getModelviewMatrixA(), getProjectionMatrixA(), getViewportA(), result);
}


public float getZDepthAtOrigin()
    {
        float[] resultf = new float[3];
        project( 320, 240, 0, resultf);
        return ((int)(resultf[2] * 1000F)) / 1000f;  // truncate to 4 decimals
    }


i use gluLookAt to move the camera around the 3d world

1  
2  
3  
GLU.gluLookAt(camX, camY, camZ,  // camera pos
            320, 240, 0, // camera target
            tiltX, tiltY, tiltZ); // camera tilt


with the code above i've been able to get ok results from the mouse when camX is at 320, camY is at 240 and camZ is changed to zooms in and out but when i change camX, or camY, the point where the mouse should be on the 3d world map starts going off, what is the correct way to do this?

to add to the problem i also have a 3d height map, i was wondering if there is a good way to get the 3d point on where the pointer clicks as done in games such as c&c: generals, tribal trouble:), dawn of war etc


thanks
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2006-01-03 20:50:23 »

Read the pixel at (320,240) in the depth-buffer. IIRC you ahd to read it as int, and scale it back using your near/far clip-planes. The int is unsigned, so you might want to cast it to a long:

float range = far-near;
float normalized = ((long)depth & 0xFFFFFFFFL) / ( (float) 0xFFFFFFFFL);
float real = normalized * range + near;

...

I didn't test it, bit it might point you in the right direction.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #2 - Posted 2006-01-03 21:05:45 »

do you mean something like

1  
2  
3  
4  
5  
6  
7  
8  
9  
 /**
     * Return the Z depth of the single pixel at the given screen position.
     */

    public static float getZDepth(int x, int y)
    {
        ByteBuffer buf = BufferUtils.createByteBuffer(64*64*4);
        GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, buf);
        return buf.getFloat();
    }
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #3 - Posted 2006-01-03 21:08:29 »

For some reason I used unsigned ints... But if float works for you, go ahead Smiley

Edit: why the massive 64*64*4 buffer? You need like 4 bytes.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #4 - Posted 2006-01-03 21:12:06 »

sorry about the above was just copying and pasting code from different places

i'm still have problems with the code currently i have

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void getCoords(int mouseX, int mouseY) {
GLU.gluUnProject( mouseX, mouseY, getZDepth(320, 240),
                                                                getModelviewMatrixA(), getProjectionMatrixA(),
                                                                getViewportA(), result);  
}


/**
* Return the Z depth of the single pixel at the given screen position.
*/

public static float getZDepth(int x, int y)
{
ByteBuffer buf = BufferUtils.createByteBuffer(4);
GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, buf);
return buf.getFloat();
}


with the code above now the mouse point on the 3d world is way off, any idea's
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #5 - Posted 2006-01-03 21:24:20 »

You have to rescale your depth anyway, because the value you retreive by reading the buffer, is 0.0 -> infinity. So use the near/far values as in my previous example.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #6 - Posted 2006-01-03 21:25:13 »

I'll try to get something working on my own system. Will report soon.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #7 - Posted 2006-01-03 22:21:59 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
         int x = 400;
         int y = 300;

         ShortBuffer dBuf = BufferUtils.createShortBuffer(1);
         Matrix4 mat = new Matrix4();
         float[] array = new float[16];
         float[][] proj = new float[4][4];
         float[][] view = new float[4][4];
         float[] obj = new float[3];

         dBuf.clear();
         glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, dBuf);
         float z = (float) (dBuf.get() & 0xFFFF) / 0xFFFF;

         MatrixUtil.download(mat, GL_PROJECTION_MATRIX);
         mat.store(array);
         for (int k = 0; k < 4; k++)
            for (int p = 0; p < 4; p++)
               proj[k][p] = array[p * 4 + k];

         MatrixUtil.download(mat, GL_MODELVIEW_MATRIX);
         mat.store(array);
         for (int k = 0; k < 4; k++)
            for (int p = 0; p < 4; p++)
               view[k][p] = array[p * 4 + k];

         boolean result = GLU.gluUnProject(x, y, z, view, proj, Overlay.getRectangle(), obj);

         if (result)
         {
            Vec3 obj3 = new Vec3(obj);
            Vec3 cam3 = new Vec3(Camera.POSITION);
            float distance = VecMath.distance3D(obj3, cam3);
            System.out.println("distance=" + distance);
         }


I know it relies on my own libraries, but I think it all speaks for itself. Give me a call when you get stuck.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #8 - Posted 2006-01-03 22:38:16 »

thx for your help, i'll give it a try
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #9 - Posted 2006-01-03 23:33:51 »

ok just tried it and it sort of works w00t (thx), but however there is a small problem, if i draw something now on the 3d world it comes nicely now under the mouse pointer, however the values i get back for the world coordinates are extreamly large

1  
2  
3  
4  
5  
 X -5011.8174 Y 8933.184 Z -17616.508
 X -9222.333 Y 14470.639 Z -15844.684
 X -9224.201 Y 14470.437 Z -15841.066
 X -9226.223 Y 14471.448 Z -15841.066
 X -9230.611 Y 14475.588 Z -15843.427


as i have a flat grid at z = 0, where a unit moves around on it towards mouse clicks, since the new values are very large it goes off the screen any ideas?

thx
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2006-01-03 23:47:28 »

I transpose my matrices under the hood when reading the matrices in opengl.

OpenGL uses transposed matrices for some awkward reason.

Give it a try.


The code works perfectly for me, so I think this is the only difference between our code.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #11 - Posted 2006-01-04 13:30:07 »

i'm not sure what you mean when you say transpose matrices, i use the following methods to get the matrices

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
public void getCoords(int x, int y) {
     GLU.gluUnProject( x, y, getZDepth(x, y), getModelviewMatrixA(), getProjectionMatrixA(), getViewportA(), result);
}



/**
* Return the Viewport data as array of 4 floats
*/

public static int[] getViewportA()
{
    IntBuffer ib = getViewport();
    int[] ia = new int[4];
    ia[0] = ib.get(0);
    ia[1] = ib.get(1);
    ia[2] = ib.get(2);
    ia[3] = ib.get(3);
    return ia;
}
   
public static IntBuffer getViewport()
{
    IntBuffer bufferViewport = BufferUtils.createIntBuffer(16);
    bufferViewport.clear();
    GL11.glGetInteger(GL11.GL_VIEWPORT, bufferViewport);
    return bufferViewport;
}
   
/**
* Return the projection matrix as a 4x4 float array
*/

public static float[][] getProjectionMatrixA()
{
    FloatBuffer b = getProjectionMatrix();
    return getMatrixAsArray(b);
}
   
public static FloatBuffer getProjectionMatrix()
{
    FloatBuffer bufferProjectionMatrix = BufferUtils.createFloatBuffer(16);
       
    bufferProjectionMatrix.clear();
    GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, bufferProjectionMatrix);
    return bufferProjectionMatrix;
}
     
/**
* Return the modelview matrix as a 4x4 float array
*/

public static float[][] getModelviewMatrixA()
{
    FloatBuffer b = getModelviewMatrix();
    return getMatrixAsArray(b);
}
   
public static FloatBuffer getModelviewMatrix()
{
    FloatBuffer bufferModelviewMatrix = BufferUtils.createFloatBuffer(16);
       
    bufferModelviewMatrix.clear();
    GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, bufferModelviewMatrix);
    return bufferModelviewMatrix;
}
   
public static float[][] getMatrixAsArray(FloatBuffer fb) {
    float[][] fa = new float[4][4];
    fa[0][0] = fb.get();
    fa[0][1] = fb.get();
    fa[0][2] = fb.get();
    fa[0][3] = fb.get();
    fa[1][0] = fb.get();
    fa[1][1] = fb.get();
    fa[1][2] = fb.get();
    fa[1][3] = fb.get();
    fa[2][0] = fb.get();
    fa[2][1] = fb.get();
    fa[2][2] = fb.get();
    fa[2][3] = fb.get();
    fa[3][0] = fb.get();
    fa[3][1] = fb.get();
    fa[3][2] = fb.get();
    fa[3][3] = fb.get();
    return fa;
}
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #12 - Posted 2006-01-04 15:51:08 »

This is how to get the transposed matrices (flipping row/column)

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public static float[][] getMatrixAsTransposedArray(FloatBuffer fb) {
    float[][] fa = new float[4][4];
    fa[0][0] = fb.get();
    fa[1][0] = fb.get();
    fa[2][0] = fb.get();
    fa[3][0] = fb.get();
    fa[0][1] = fb.get();
    fa[1][1] = fb.get();
    fa[2][1] = fb.get();
    fa[3][1] = fb.get();
    fa[0][2] = fb.get();
    fa[1][2] = fb.get();
    fa[2][2] = fb.get();
    fa[3][2] = fb.get();
    fa[0][3] = fb.get();
    fa[1][3] = fb.get();
    fa[2][3] = fb.get();
    fa[3][3] = fb.get();
    return fa;
}

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #13 - Posted 2006-01-04 18:29:45 »

thx for the code update but transposing the matrices doesn't seem to be working i must be doing something wrong, now the values i get are extreamly small
1  
2  
3  
4  
5  
6  
7  
8  
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5
 X 0.0019316514 Y -4.2342854E-4 Z -5.4228705E-5

Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #14 - Posted 2006-01-04 19:06:37 »

ok i've just managed to get so sortta good results, i have switched back to the non-transposed matricies, i was using grid lines before as a plane and i think the rays from readpixel where going right through it, when i switched to a quad plane it seems to work nicely, i have also now turned on the heightmap and it seems to work nicely with it, however this only works when the mouse is actually on the plane and not in 3d space.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #15 - Posted 2006-01-04 19:34:08 »

read-pixels reads from the depth-buffer, and when you are drawing lines, instead of filled shapes, there isn't anything written to the depth-buffer inside the shape that the lines make up.

Also be sure that you read the projection/modelview-matrices at the right time. If you are rendering the 2D overlay, and read the projection-matrix from there, you can't get the correct coords of 3d-space because you are working with the wrong matrix.

I think that is obvious, but from the problem you have, that might be the problem.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #16 - Posted 2006-01-05 10:33:06 »

Is the above helpful to you?

I'd like to help you with this one.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 80
Projects: 15


★★★★★


« Reply #17 - Posted 2006-01-05 18:38:31 »

ok thx for the help i've got it working now, was indeed the fact that i was using lines, switching to quads has solved the problem, i'll let you know if i have any other issues.

thx
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (40 views)
2014-12-09 22:41:13

BurntPizza (75 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (47 views)
2014-11-29 21:32:03

toopeicgaming1999 (113 views)
2014-11-26 15:22:04

toopeicgaming1999 (100 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!