Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (575)
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  
  a few picking questions  (Read 1358 times)
0 Members and 1 Guest are viewing this topic.
Offline Wizumwalt

Junior Duke




Java games rock!


« Posted 2005-02-27 19:22:36 »

I have a few questions as I'm stilling trying to get picking working correctly.

Q1) If the objects I'm drawing on screen are drawn as a mesh (I use gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)), will I get a hit if I'm doing picking and I select the center of the polygon? (i.e. I'm guessing not cause there's nothing there as my polygon is not filled in. It's just a wire frame) I'm supposed to get a hit if I drag

Q2) In my mouseDragged(MouseEvent me) method, I'm setting a select mode so that I can process the Hits in my display() method when I drag my mouse like a sweep selection through the mesh of polygons. Of cours I don't have this working now, but my problem is that I don't even see any hits being processed. Hits most of the time turns up as 0. Do I have the code below correct to do this?

Note: I'm not trying to select the entire object as I only have one geometry displayed, rather, I'm trying to select the individual polygon of the mesh of my object which is displayed as a wire frame. So not sure I'm doing the code correct so far to do this.

   public void display(GLDrawable drawable) {
       GL gl = drawable.getGL();
       GLU glu = drawable.getGLU();
       this.gldrawable = drawable;

       switch (cmd) {
           case UPDATE:
           ...
           break;

           case SELECT:
               int hits = 0;
               int buffSize = 512;
               int[] viewPort = new int[4];
               IntBuffer selectBuffer = BufferUtils.newIntBuffer(buffSize);

               double x = (double) prevMouseX;
               double y = (double) prevMouseY;

               gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort);
               gl.glSelectBuffer(buffSize, selectBuffer);
               gl.glRenderMode(GL.GL_SELECT);
               gl.glInitNames();
               gl.glPushName(0);
               gl.glMatrixMode(GL.GL_MODELVIEW);
               gl.glPushMatrix();
               gl.glLoadIdentity();
               glu.gluPickMatrix(x, (double) viewPort[3] - y,
                   7.0d, 7.0d, viewPort);

               // glu.gluOrtho2D(0.0d, 1.0d, 0.0d, 1.0d);
               // gl.glOrtho(0.0, 400.0, 0.0, 300.0, -1000, 1000);

               if (selectedFile) {
                   model.draw();
               }

               gl.glMatrixMode(GL.GL_MODELVIEW);
               gl.glPopMatrix();
               gl.glFlush();

               hits = gl.glRenderMode(GL.GL_RENDER);
               processHits(hits, selectBuffer);

               cmd = UPDATE;

               break;
       }
   }

    public void processHits(int hits, IntBuffer buffer) {
       System.out.println("---------------------------------");
       System.out.println(" HITS: " + hits);
       int offset = 0;
       int names;
       float z1, z2;

       for (int i = 0; i < hits; i++) {
           System.out.println("- - - - - - - - - - - -");
           System.out.println(" hit: " + (i + 1));

           names = buffer.get(offset);
           offset++;
           z1 = (float) buffer.get(offset) / 0x7fffffff;
           offset++;
           z2 = (float) buffer.get(offset) / 0x7fffffff;
           offset++;

           System.out.println(" number of names: " + names);
           System.out.println(" z1: " + z1);
           System.out.println(" z2: " + z2);
           System.out.println(" names: ");

           for (int j = 0; j < names; j++) {
               System.out.print("       " + buffer.get(offset));

               if (j == (names - 1))
                   System.out.println("<-");
               else
                   System.out.println();

               offset++;
           }

           System.out.println("- - - - - - - - - - - -");
       }
   }

   // mouse down w/ left ctrl means I want to select
   // the polygon I'm in and any that I drag across.
   public void mouseDragged(MouseEvent me) {
       int x = me.getX();
       int y = me.getY();

       if (SwingUtilities.isLeftMouseButton(me)) {
           if (me.isControlDown()) {
               cmd = SELECT;

               prevMouseX = x;
               prevMouseY = y;
           }
           ...
           this.gldrawable.display();
       }
...
Offline Schabby

Junior Duke




The Receding Brow Worm will eat your code!


« Reply #1 - Posted 2005-03-03 12:28:54 »

Hi, maybe that helps:

http://user.cs.tu-berlin.de/~schabby/PickingExample.java

It's an example class about picking...

I also will run in my project in a similar problem (picking on vertex Arrays/ Mesh). But I did not think much about it yet. All I do until now is that I draw my scene differently in GL_SELECT and GL_RENDER mode. In GL_RENDER mode I simply flush a vertex array in the pipeline, but in GL_SELECT mode, I draw my mesh triangle by triangle. Each triangle is  named so that I can afterwards determine which triangle was selected. That requires of course that I keep the triangles of the mesh somewhere in the memory as well as my vertex arrays, which is redundant. But it works pretty well.

Q1) OpenGl uses the depth buffer to get the information on which pol. you clicked (in SELECT mode, not "Color Coding"). Since the center of you pol. is not drawn, I think that there is also no depth value in the center of the polygon in the depth buffer.

Offline Wizumwalt

Junior Duke




Java games rock!


« Reply #2 - Posted 2005-03-03 18:08:05 »

Hey,

I've got pretty much exactly what you've got going so far. I rotate my geometry when the mouse button is down, but when the CTRL key is also down at the same time as the mouse, I'm going to select and highlight the polygon that my pointer is in (and hopefully do a sweep selection). Otherwise, I'd just like to hover over a polygon and highlight the specific polygon in the mesh my pointer is hovering over.

From the code I originally posted above, my model.draw() method has a code snipped like below which does all my mesh triangles. So when I'm in GL_SELECT mode, The only real difference is the processing of hits. Like you, I also have each triangle drawn w/ an Id assigned to that triangle and all my triangles are stored in memory.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
            ...
            for (int i = 0; i < vertexSize; i++) {
                Node node = (Node) nodes.get(new Integer(nodeID[i]));

                vertexBuffer.put(idx++, (float) node.getX());
                vertexBuffer.put(idx++, (float) node.getY());
                vertexBuffer.put(idx++, (float) node.getZ());
            }

            gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
            gl.glColor3f(1.0f, 1.0f, 1.0f);
            gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

            if (vertexSize == 2) {
               ...
            }
            else if (vertexSize == 3) {
                gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertexBuffer);
                gl.glDrawArrays(GL.GL_TRIANGLES, 0, 8);
            }

            gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
            ...

The problem I'm having though is when I click inside a polygon, how do I find the lines closest around the pointer so I can highlight those lines or maybe even the surface of that polygon. I guess what I'm wondering is, how is it afterwards that you determine which triangle was selected? Or are you selecting the individual triangles yet?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Schabby

Junior Duke




The Receding Brow Worm will eat your code!


« Reply #3 - Posted 2005-03-04 01:03:39 »

In my case I indeed only require the selection of individual triangles, not polygons. Embarrassed
Quote
I guess what I'm wondering is, how is it afterwards that you determine which triangle was selected?


When you click on your viewport, OpenGL shoots at this position in the deph buffer. All hits are then listed descending (with the first entry as the most closest one to the cursor) in the hit record together with the Id/Name of the hit and some other values. Your processHits method prints this list. With the help of the Id/Name from the first hit entry, you can determine on which triangle you clicked. As you know, you need to store the Id/Name of each triangle, so that you can retrieve the selected triangle with the ID/Name from the hit record. But I think this is no problem to you.

Quote
The problem I'm having though is when I click inside a polygon, how do I find the lines closest around the pointer so I can highlight those lines or maybe even the surface of that polygon


You need additional information for each triangle to which polygon it belongs. With this available, you can easily back reference after hitting a triangle which polygon you selected.
However, I think it is not trivial how to determine which triangle belongs to which polygon, since different polygons share often the same vertices. But I would bet that there are algorithms available in which you pass as input your mesh and some polygon criteria and get as output a list of adjacent polygons.

Offline Wizumwalt

Junior Duke




Java games rock!


« Reply #4 - Posted 2005-03-04 20:03:23 »

AFAIK, even though I've used gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) to draw the mesh instead of filling them in, I'm still drawing triangles.

   gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertexBuffer);
   gl.glDrawArrays(GL.GL_TRIANGLES, 0, 8);

When a hit is processed, a hit record is returned w/ the following data:

- number of names on name stack when hit occurred.
(ok, so I have one name on the stack which is always 0)
- min and max window coordinate z-values of vertices of the primitive that intersected the viewing volume.
(I don't see that these Z values tell me anything, they're usually always 1.0 and 1.0)
- contents of name stack at time of hit w/ bottom most element fist.
(I always only have one name on the stack, named 0)

So I've drawn my triangles which have names (or id's), but the id's just stay in memory. I think what I'm missing here is the association of the name of the triangle and the name of the hit record. Isn't the name of the hit record always going to be '0', or whatever integer is hardcoded in the gl.glPushName() method inside processHits()?

I just thought of something. Should I be doing a gl.glPushName(myTriangleId) at the time I draw the object in GL_SELECT mode? Then the record name (or the name pushed on the name stack when a hit occurs) would be the same as the triangle id. But the problem is, I iterate through a large HashMap of Triangles and while I'm looping through them, I'd fill up the name stack with way more than the 64 it can handle before I got back out of GL_SELECT mode.

I'm missing something here terribly.
Offline Schabby

Junior Duke




The Receding Brow Worm will eat your code!


« Reply #5 - Posted 2005-03-05 00:40:19 »

Seems I did not get your problem before, sorry for that.

OpenGL implementations are supposed to have a name stack capacity for at least 64 names, that's true, but you don't need one stack level for each triangle. While you loop though your HashMap, you can replace the name on the top of the stack (with glLoadName()) and then draw your triangle/polygon/line/point. The name on the top of the name stack is then assigned to your drawn object.

Here is my code that I use for picking on my terrain. The terrain has 255*255 selectable quads in GL_SELECT mode (which is bad style, I know, but illustrative here). At the same time, the stack never contains more the two names.

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  
// called when user pressed a mouse button
private void displaySelect() {
int[] viewport = new int[4];
       
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
gl.glSelectBuffer(selectionBuffer.capacity(), selectionBuffer);

gl.glRenderMode(GL.GL_SELECT);
       
gl.glInitNames();                      
       
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();                  
       
gl.glLoadIdentity();                  
       
glu.gluPickMatrix(mouseX, viewport[3] - mouseY, 1.0d, 1.0d, viewport);      

glu.gluPerspective(45, ratio,1, 200);          
gl.glPushName(-1);
drawQuadSelectionTerrain();
gl.glPopMatrix();                      

int hits = gl.glRenderMode(GL.GL_RENDER);
mode = GL.GL_RENDER;
       
processHits(hits, selectionBuffer);
       
gl.glMatrixMode(GL.GL_MODELVIEW);
       
}

private void drawQuadSelectionTerrain() {
    int counter =0;
    final int skal=4;
    for(int x =0;x<heightField.length-1;x++) {
        for(int y =0;y<heightField[0].length-1;y++) {

            // replaces the element on the top
            // of the name stack with counter
            gl.glLoadName(counter++);

            // the quads are drawn filled
            gl.glBegin(GL.GL_QUADS);
            gl.glVertex3i(x*skal, y* skal, heightField[x][y]);
            gl.glVertex3i((x+1)*skal, y* skal, heightField[x+1][y]);
            gl.glVertex3i((x+1)*skal, (y+1)* skal, heightField[x+1][y+1]);
            gl.glVertex3i(x*skal, (y+1)*skal, heightField[x][y+1]);
            gl.glEnd();

        }
    }

}


The process hits method is the same you have. If you still have problems, you can send me (johannes.schaback at gmail.com) your code and I will try to get it working.

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.

Longarmx (34 views)
2014-10-17 03:59:02

Norakomi (25 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (26 views)
2014-10-15 16:18:58

TehJavaDev (50 views)
2014-10-14 00:39:48

TehJavaDev (50 views)
2014-10-14 00:35:47

TehJavaDev (40 views)
2014-10-14 00:32:37

BurntPizza (63 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (74 views)
2014-10-11 22:30:10
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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!