Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (575) Games in Android Showcase (154) games submitted by our members Games in WIP (624) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Picking  (Read 3796 times) 0 Members and 1 Guest are viewing this topic.
DonCrudelis

Junior Devvie

 « Posted 2004-08-15 18:36:05 »

Hi all.

I have made a picking demo but when I pick the delay is up to 50 ms (!!), that's a long delay if we want a fast engine...
I have a terrain (which is pretty big), and that's the problem..

Does the picking code pick behind objects, in my case, behind a hill?

How to make it faster?

Emil Alonzo
Jacke

Junior Newbie

Java games rock!

 « Reply #1 - Posted 2004-08-16 11:23:57 »

Hi,
here my solution for terrainpicking:

I cast a ray from eye through intersection with a ground plane. Then i go step by step on this ray forward. If the y-coordinate on the ray at x,y is smaler than the y- coordinate on the terrain(x,y) i go back on the ray, in smaller steps. If the y-coordinate of the ray at x,y is close enough to the y-coordinate at terrain(x,y) i got the intersection point with the terrain.
You do not get the 100% right position with this solution, but you can fit the solution to your needs(performance,precision) by changing the variables precision and heightModifer
I think this solution could be pretty fast if you find the right values for the variables.

 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  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100  101  102  103  104  105  106  107  108  109  110  111  112  113 `//Umwandlung von Screen- in Worldkoordinaten auf einem Terrain    public Vector3f getTerrainIntersection(Point mousePos, Point3f camPos, Point3f lookat)    {          double r=(mousePos.x - screenWidth/2.0f)/(screenWidth/2.0f)*0.935f;            double s=((screenHeight/2.0f - mousePos.y)/(screenHeight/2.0f)) * (screenHeight/screenWidth)*0.935f;                        //Vector d from Camera to Lookat            Vector3f d=new Vector3f();            d.x=camPos.x-lookat.x;            d.y=Math.abs(camPos.y-lookat.y);            d.z=camPos.z-lookat.z;                        //Vector  v1 parallel to Ground and perpendicularly to Vector d            Vector3f v1=new Vector3f();            v1.x=d.z;            v1.y=0;            v1.z=-d.x;            v1.normalize();                        // Crossproduct of d and v1            Vector3f v2= new Vector3f();            v2.cross(d,v1);            v2.normalize();                        //Plane to project the pointer            Vector3f v=new Vector3f();            v.x=(float)(lookat.x+r*v1.x+s*v2.x); //rayDir=v.x            v.y=(float)(lookat.y+s*v2.y);            v.z=(float)(lookat.z+r*v1.z+s*v2.z);                        /*Intersection with x,z-Plane             *Line: l=camPos+w(v-camPos)             *Plane: p=sx*(1;0;0)+sz*(0;0;1)             *l=p ....             */                        float w=(float)(-camPos.y/(v.y-camPos.y));            float sx=(float)(camPos.x+w*(v.x-camPos.x));            float sz=(float)(camPos.z+w*(v.z-camPos.z));                        //Plane            Vector3f planeInter=new Vector3f();            planeInter.x=sx;            planeInter.y=0;            planeInter.z=sz;                                                         /*Find Intersection with Terrain           Eine Gerade wird durch Auge und Planeintersection gezogen           Dann wird sich schrittweise vom Auge aus der planeintersection genährt           und dabei überprüft um die y-Koordinate der Geraden mit der y-koordinaten           des Terrains an diesem x,z punkt übereinstimmt.           Ist dies in etwa der Fall(Präzisionsgrad) dann ist der Schnittpuntk mit dem            Terrain gefunden.           Durch Einstellen der Werte von heightModifer und precision kann sowohl            Qualität als auch Rechenaufwand angepasst werden.          */                    Vector3f pointerPos=new Vector3f(camPos);                    planeInter.x-=camPos.x;          planeInter.y=camPos.y;          planeInter.z-=camPos.z;                              rayDir.x=v.x-camPos.x;          rayDir.y=v.y-camPos.y;          rayDir.z=v.z-camPos.z;          heightModifer=planeInter.length()/70;                    rayDir.normalize();                                                 precision=heightModifer/15; //Präzision der Berechnung          n=1;          runs=0;                                                 if(rayDir.y<-0.01f)          {                                                                    while(Math.abs(pointerPos.y - Globals.terrain.getY(pointerPos.x,pointerPos.z))>precision                                   && pointerPos.y > 0 && runs<200 && n< 15000)          {                if(pointerPos.y > Globals.terrain.getY(pointerPos.x,pointerPos.z))                n+=heightModifer;                                            else                n-=precision/3;                                                          pointerPos.x=camPos.x+n*rayDir.x;                pointerPos.y=camPos.y+n*rayDir.y;                pointerPos.z=camPos.z+n*rayDir.z;                                runs++;                                                }          }                    else          {                pointerPos.x=camPos.x+5000*rayDir.x;                pointerPos.y=camPos.y+5000*rayDir.y;                pointerPos.z=camPos.z+5000*rayDir.z;          }                       //System.out.println("Runs: "+runs);          /*if(runs>mostRuns)          mostRuns=runs;          stem.out.println("Most runs: "+mostRuns);          System.out.println("Heightmodifer: "+heightModifer);          System.out.println("Precision: "+precision);*/              return pointerPos;    }`

Hope it helps

Jacke
DonCrudelis

Junior Devvie

 « Reply #2 - Posted 2004-08-16 11:32:06 »

Thanks for the help!

Alonzo
Zorqu

Senior Newbie

Java games rock!

 « Reply #3 - Posted 2005-03-03 00:49:28 »

can someone tell me what "rayDir" is and how do I get it?
Macca

Senior Newbie

Java games rock!

 « Reply #4 - Posted 2005-03-03 12:15:19 »

It think it's a vector (correct me if i'm wrong).

 1 `Vector3f rayDir = new Vector3f();`
above the
 1  2  3 `rayDir.x=v.x-camPos.x;                rayDir.y=v.y-camPos.y;                rayDir.z=v.z-camPos.z;`
bit and it should work ok.
Amos Wenger

Senior Devvie

Everything's possible, but not everything's fun...

 « Reply #5 - Posted 2005-03-03 14:37:44 »

Have anybody a function to get :
- The Shape3D that is picked
- The Triangle that is picked
- ( Optionally ) the coordinates of the intersection

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
ewills

Junior Devvie

Java skeletal animation systems rock!

 « Reply #6 - Posted 2005-03-03 15:18:47 »

DonCrudelis

Junior Devvie

 « Reply #7 - Posted 2005-03-03 15:43:39 »

Have a look for the geometry directory in xithtk, there is some code.

Please report to me if some code is missing or buggy.

This is the picking code:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17 `            Point3f point= new Point3f();            Vector3f vec = new Vector3f();            getCanvas3D().createPickRay(x, y, point, vec);            Ray ray = new Ray(point, vec);            Point3f p = null;            Triangle triangle = null;                        for (Triangle t : getTriangles(shape)) {                Point3f temp = t.intersects(ray);                if (temp != null) {                    p = temp;                    triangle = t;                    System.out.println("Coordinate of intersection=" + p);                    break;                }            }            `

getTriangles() :

 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 `    public Triangle[] getTriangles(Shape3D poShape3D) {        Triangle[] aoTriangle = null;        Vector3f oVector3f = new Vector3f();        poShape3D.getLocalToVworld().getTranslation(oVector3f);        Geometry oGeometry = poShape3D.getGeometry();        if (oGeometry instanceof GeomIndexedContainer) {            GeomIndexedContainer oGeomIndexedContainer = (GeomIndexedContainer)oGeometry;            int[] aiIndices = oGeomIndexedContainer.getIndex();            aoTriangle = new Triangle[aiIndices.length / 3];            for (int i = 0, j = 0; i < aiIndices.length; i++, j++) {                Point3f oPoint3f1 = new Point3f();                Point3f oPoint3f2 = new Point3f();                Point3f oPoint3f3 = new Point3f();                oGeometry.getVertex(aiIndices[i], oPoint3f1);                oGeometry.getVertex(aiIndices[i + 1], oPoint3f2);                oGeometry.getVertex(aiIndices[i + 2], oPoint3f3);                oPoint3f1.add(oVector3f);                oPoint3f2.add(oVector3f);                oPoint3f3.add(oVector3f);                aoTriangle[j] = new Triangle(oPoint3f1, oPoint3f2, oPoint3f3);                i += 2;            }        } else {            aoTriangle = new Triangle[oGeometry.getVertexCount() / 3];            for (int i = 0, j = 0; i < oGeometry.getVertexCount(); i++, j++) {                Point3f oPoint3f1 = new Point3f();                Point3f oPoint3f2 = new Point3f();                Point3f oPoint3f3 = new Point3f();                oGeometry.getVertex(i, oPoint3f1);                oGeometry.getVertex(i + 1, oPoint3f2);                oGeometry.getVertex(i + 2, oPoint3f3);                oPoint3f1.add(oVector3f);                oPoint3f2.add(oVector3f);                oPoint3f3.add(oVector3f);                aoTriangle[j] = new Triangle(oPoint3f1, oPoint3f2, oPoint3f3);                i += 2;            }        }        return aoTriangle;    }    `

I don't know how to optimize it but please somebody try.
I don't even know how to pick the whole universe, I only know how to check if a shape is being picked, but triangle and point of intersection is in for the moment .

Alonzo
Zorqu

Senior Newbie

Java games rock!

 « Reply #8 - Posted 2005-03-04 23:55:12 »

Thanks Macca, I've had some more time to look at this and realized Globals.terrain.getY is also undefined.  Any ideas about that one?

Globals.terrain.getY(pointerPos.x, pointerPos.z)
Zorqu

Senior Newbie

Java games rock!

 « Reply #9 - Posted 2005-03-05 12:03:14 »

I am getting so frustrated with this, I can't get this to work.  Most of this stuff I am not following.  I either need a detailed tutorial to follow or some code I can plug in and run with.

I have my eye at (camX, camY, camZ) and I have it looking at (viewX, viewY, 0)  I'm just trying to get the X,Y coords where the user clicked Z will always be 0 its a flat terrain... I've spent so much time on this and still have nothing

Macca

Senior Newbie

Java games rock!

 « Reply #10 - Posted 2005-03-05 14:17:57 »

Yeah i know, it can be really frustrating to do something so obvious i spent ages trying to understand this!

The terrain.getY() is getting the height of point x, z on your terrain. y is up, not z!

The Globals.terrain is your Terrain class (if you're using the demo i think you can just delete the "Globals." bit.) otherwise replace this with the name of your Terrain object. I'm not sure you need this if your terrain's going to be flat because its always going to return 0, but i guess its best to leave it in incase you have mountains and stuff later.

Are you using Terrain or have you just got a flat shape? If so, this method won't help you, check out DonCrudelis' code above. You should be able to just plug it in, though you might have to change the getCanvas3D() bit for the name of your canvas object. 'x' and 'y' are your mouse points on the screen, 'shape' is your terrain shape. I think p will return the point you're looking for.

Hope this helps!
Zorqu

Senior Newbie

Java games rock!

 « Reply #11 - Posted 2005-03-05 14:53:25 »

I have got a flat shape... a quad.  So I should try DonCrudelis' code or is that just for terrain object?  Here is what I'm doing now, I changed Global.terrain.getY to 0, and I pass in Z for Y and Y for Z since I have Y as up.

 1  2  3  4  5  6  7  8  9 `      public void mouseClicked(MouseEvent e) {            Vector3f vect = new Vector3f();            vect = getTerrainIntersection(e.getPoint(), new Point3f(camX, camZ,                        camY), new Point3f(viewX, 0, viewY));            System.out.println(vect.x); // x coord            System.out.println(vect.z); // y coord                        isViewChangeScheduled = true;      }`

What I get out of this are values very close to my viewX and viewY I put into it.  My viewX=5 and viewY=5 i get output like:
X = 5.0227056
Y = 4.992122
X = 5.004961
Y = 5.0184546
X = 4.9696717
Y = 5.014441

clicking in various places - this is obviously not what I want =/

oh yeah, and this is with the camera overhead looking straight down, if I change the angle of it then it gives me different numbers, but still nothing close to what I want
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #12 - Posted 2005-03-07 14:57:12 »

Hi

As far as I got to know this stuff, we still have to enumerate through all Triangles in the world - this is for big worlds a really big problem. Has anybody got a solution for this? I think a good selection algorithm could very much increase the  speed.
I don't even know if something of this kind already exists in xith/jogl, because a good renderer should also use this kind of thingi, because a renderer that tries to render something behind the view is a lot slower than a renderer thet only renders stuff in front of the view.

:: JOODE :: Xith3d :: OdeJava ::
Zorqu

Senior Newbie

Java games rock!

 « Reply #13 - Posted 2005-03-08 03:25:10 »

I found another post mentioning Canvas3D.createPickRay().  I had to download the method from CVS but it was worth it, helped me a ton I think I got it figured out now.  Thanks guys!

createPickRay() from CVS
 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 `    public void createPickRay(int x, int y, Point3f o, Vector3f d) {        float w = (float) canvas.getWidth();        float h = (float) canvas.getHeight();        float a = h / w;        if (view.getProjectionPolicy() == View.PERSPECTIVE_PROJECTION) {            // normalize the pixel location to between -1.0 and 1.0 and modify the x            // coordinate to take aspect ratio into account.            float rx = (2.0f * (float) x / w - 1.0f) / a;            float ry = 2.0f - 2.0f * (float) y / h - 1.0f;            // calculate the distance between viewer and view plane.            float vpd = 1.0f / (float) Math.tan(view.getFieldOfView());            // originate the ray at the local origin of the viewer and direct it            // toward the local position of the click in the view plane.            o.set(0.0f, 0.0f, 0.0f);            d.set(rx, ry, -vpd);            d.normalize();        } else {            // normalize the pixel location to between -1.0 and 1.0 and modify the y            // coordinate to take aspect ratio into account.            float rx = 2.0f * (float) x / w - 1.0f;            float ry = a * (2.0f - 2.0f * (float) y / h - 1.0f);            // originate the ray at local position of the click in the view plane            // and direct it along the -Z axis.            float s = view.getScreenScale();            o.set(s * rx, s * ry, 0.0f);            d.set(0.0f, 0.0f, -1.0f);        }        // transform the ray into world space.        view.getTransform().transform(o);        view.getTransform().transform(d);    } `
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #14 - Posted 2005-03-08 14:13:22 »

Hi

I've got two things to say:
1.
I've got a very good way of checking collisions with the whole scene, without calculating intersections with all Triangles. It works like this:
 1  2  3  4  5  6  7  8  9  10  11  12  13 `Vector toLookCloserAt = new Vector();Stack s = new Stack();s.push(root);while(!s.empty()) {  Node n = (Node) s.pop();  if(n.getVworldBounds().intersect(origin, direction) { //Intersection with ray    if(n instanceof Group) {       s.addAll( ((Group) n).getChildren);    }    else toLookCloserAt.add(n);  }}//now you only have to test the Shape3D's in toLookCloserAt`

2.
DonCrudelis had some code for getting the triangles from a Shape3D. But it only seems to work for GeomIndexedContainer and not for any other kinds of Geometry, too.
Has anybody a better solution to get the Triangles than by testing for all kinds of Geometry. The major problem here for me is, that GeometryStripArray saves the stuff differently than a simple Trianglearray. At least I think so!

:: JOODE :: Xith3d :: OdeJava ::
Amos Wenger

Senior Devvie

Everything's possible, but not everything's fun...

 « Reply #15 - Posted 2005-03-08 16:58:08 »

Quote
Hi

I've got two things to say:
1.
I've got a very good way of checking collisions with the whole scene, without calculating intersections with all Triangles. It works like this:
 1  2  3  4  5  6  7  8  9  10  11  12  13 `Vector toLookCloserAt = new Vector();Stack s = new Stack();s.push(root);while(!s.empty()) {  Node n = (Node) s.pop();  if(n.getVworldBounds().intersect(origin, direction) { //Intersection with ray    if(n instanceof Group) {       s.addAll( ((Group) n).getChildren);    }    else toLookCloserAt.add(n);  }}//now you only have to test the Shape3D's in toLookCloserAt`

2.
DonCrudelis had some code for getting the triangles from a Shape3D. But it only seems to work for GeomIndexedContainer and not for any other kinds of Geometry, too.
Has anybody a better solution to get the Triangles than by testing for all kinds of Geometry. The major problem here for me is, that GeometryStripArray saves the stuff differently than a simple Trianglearray. At least I think so!

Okay, this advance the Picking discussion.
I'll see if I can do a little function to get all Triangle in it ( even if there is TriangleStrip information, or Quad ).
I think there is a problem only if the Geom is composed of segments instead of faces ( triangles or quads ).

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #16 - Posted 2005-03-09 12:24:21 »

I think there really has to be a way, because the renderer has to do it in some way too - and testing for all kinds of classes would be no good object oriented programming.

Some things I found out :

GeomContainer has a Function called getVertexFormat() - it seems to return an integer - what the int means i think is saved in the static variables of GeomContainer. This might be the way to get an idea of how to interpret the VertexData without testing for all kinds of Geometry classes. We would still have to test for all the different types   .

Actually I think there must be a better way, because the Geometry stuff wouldn't be able to be extended then.
Something I also stepped across is GeometryTranslocator. Where does it fit in?

:: JOODE :: Xith3d :: OdeJava ::
Macca

Senior Newbie

Java games rock!

 « Reply #17 - Posted 2005-03-11 17:05:36 »

I'm having some trouble with picking. I've got my pickable objects arranged in a BranchGroup. When I add a node to the group its bounds get set to some default value which is totally wrong.

All the nodes also get set to this same value even if I manually set the bounds and turn off autocompute before hand. When I try and pick them they all intersect no matter where I click.

Anyone got any ideas what I'm doing wrong?
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #18 - Posted 2005-03-11 17:37:25 »

The Bounds should autocompute correctly.

Are you testing this, by showing the bounds with setShowBounds ? - It doesn't work correctly.

:: JOODE :: Xith3d :: OdeJava ::
Macca

Senior Newbie

Java games rock!

 « Reply #19 - Posted 2005-03-12 18:09:28 »

Was using breakpoints but I've got this sorted now thanks, used the view.pick instead
aNt

Senior Devvie

AFK

 « Reply #20 - Posted 2005-05-05 07:33:01 »

i seem to be running into problems with all this

i have tryed useing the view.pick(...) and the also
implemented the createPickRay(...)...

1. view.pick(...) just doesnt seem to work.. my nodes
are node.setPickable(true); When i click the mouse
sending the x, y location of the mouseClick (over a
shape) it doesnt work. i have pritty much copyed the
test case and its just not having it - do the PolygonAttributes
matter with picking? what is if am using transparancy?

2. createPickRay(..) i just dont no how to get this to
work? how do i implement it so it returns me what
i clicked on? every time i use it with:
 1  2  3  4  5 `     Point3f point = new Point3f(0, 0, 50f);    Vector3f vec = new Vector3f(0, 0, 1);    createPickRay(x, y, point, vec);    Ray ray = new Ray(point, vec);    System.out.println("ray, x, y: " + ray + ", " + x + ", " + y);`
the ray doesnt seem to change when i click the mouse
all over the canvas? I dont need to no where on a shape
i clicked for now- just what shape got clicked..

can anyone help here? i guess i've missed the point
somewhere....
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #21 - Posted 2005-05-05 08:06:53 »

Here's the whole code for picking that also gets you the position and the shape:
 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  85  86  87  88  89  90  91  92  93  94  95  96  97  98 `Vector branchGroups;public PickResult pick(int x, int y) {  Point3f o = new Point3f();  Vector3f d = new Vector3f();  canvas.createPickRay(x,y,o,d);  TreeSet intersecting = new TreeSet();  Stack s = new Stack();  Point3f pos = new Point3f();  Vector3f pos1 = new Vector3f();  Vector3f pos2 = new Vector3f();  Vector3f pos3 = new Vector3f();  boolean result;  boolean nopos;  for(Enumeration e = branchGroups.elements(); e.hasMoreElements(); ) {     BranchGroup tg = (BranchGroup) e.nextElement();     s.clear();     s.push(tg);     while(!s.empty()) {       Node n = (Node) s.pop();       Bounds b = n.getVworldBounds();       result = false;       nopos = false;       if(b instanceof Sphere) result = ((Sphere) b).rayIntersection(o, d, pos);       else if(b instanceof Box) result = ((Box) b).rayIntersection(o, d, pos);       else if(b instanceof ConvexHull) result = ((ConvexHull) b).rayIntersection(o, d, pos);       else {         result = b.intersect(o,d);         nopos = true;       }       if(result) {         if(Group.class.isInstance(n)) {           Group g = (Group) n;           s.addAll(g.getChildren());         }         else {           float dist;           if(!nopos) dist = pos.distanceSquared(o);           else dist = 0;           if(n instanceof Shape3D) intersecting.add(new PickResult(c.getVObject(),(Shape3D) n, dist));         }       }     }   }   Triangle t = new Triangle();   Point3f transOrigin = new Point3f();   Vector3f transDirection = new Vector3f();   float closestIntersect = Float.POSITIVE_INFINITY;   PickResult nearest = null;   for(Iterator i = intersecting.iterator(); i.hasNext(); ) {     PickResult r = (PickResult) i.next();     Geometry geom = r.getGeom();     GeometryArray geomArr;     if(geom instanceof GeometryArray) geomArr = (GeometryArray) geom;     else if(geom instanceof GeometryTranslocator) geomArr = ((GeometryTranslocator) geom).getGeometry();     else geomArr = null; //User-defined Geometry is not supported - should be changed     transOrigin.set(o);     r.transform(transOrigin);     transDirection.set(d);     r.transform(transDirection);     if(geomArr != null) {       if(geomArr instanceof QuadArray) {         System.out.println("quad");       }       if(geomArr instanceof TriangleArray) {         int length = geomArr.getVertexCount();         for(int j = 0; j < length; j+=3) {           geomArr.getVertex(j,pos1);           geomArr.getVertex(j+1,pos2);           geomArr.getVertex(j+2,pos3);           t.set(pos1,pos2,pos3);           float f = t.test(transOrigin,transDirection,closestIntersect);           if(f != -1) {  // there is a collision             f = f/transDirection.length();             if(f < closestIntersect) {               closestIntersect = f;               r.setDistance(f);               nearest = r;             }           }         }       }       if(geomArr instanceof TriangleFanArray) {         System.out.println("tri-fan");       }       if(geomArr instanceof TriangleStripArray) {         System.out.println("tri-strip");       }     }   }   if(nearest != null) {   Point3f p  = new Point3f();   p.scaleAdd((float)Math.sqrt(nearest.getDistance()),d,o);   nearest.setPos(p);   return(nearest);  }  return(null);}`

 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 `    public class Triangle {        Vector3f p1;        Vector3f p2;        Vector3f p3;        Point3f temp;        Vector3f t1,t2,t3;        public Triangle() {            temp = new Point3f();            t1 = new Vector3f();            t2 = new Vector3f();            t3 = new Vector3f();        }                public void set(Vector3f p1, Vector3f p2, Vector3f p3) {            this.p1 = p1;            this.p2 = p2;            this.p3 = p3;        }                public boolean testForIntersection(Tuple3f q, Vector3f dir) {            temp.scaleAdd(100000,dir,q);            int i = sign3D(temp,p1,q,p2);            int j = sign3D(temp,p3,p2,q);            int k = sign3D(temp,p1,p3,q);            if(i == 0 && j == 0) return true; // intersects in C            if(i == 0 && k == 0) return true; // intersects in A            if(j == 0 && k == 0) return true; // intersects in B            if(i == 0 && j == k) return true; // intersects in AC            if(j == 0 && i == k) return true; // intersects in BC            if(k == 0 && j == i) return true; // intersects in AB            if(i == j && j == k) return true; // intersects inside            return false; // does not intersect        }        public int sign3D(Tuple3f a, Tuple3f b, Tuple3f c, Tuple3f d) {            Matrix3f m = new Matrix3f(a.x-d.x, a.y-d.y, a.z-d.z,                                      b.x-d.x, b.y-d.y, b.z-d.z,                                      c.x-d.x, c.y-d.y, c.z-d.z);            float det = m.determinant();            if(det > 0.00001) return 1;            else if(det < -0.00001) return -1;            else return(0);        }        public float intersect(Point3f orig, Vector3f dir) {            t3.set(orig);            float     r, a, b;            p2.sub(p1);            p3.sub(p1);            t1.cross(p2, p3);            if (t1.length() == 0) {                return(-1);            }            t3.sub(p1);            a = -t1.dot(t3);            b = t1.dot(dir);            if ((float)Math.abs(b) < 0.00001) {                return(-1);            }            r = a / b;            if (r < 0.0) {                return -1;            }            return r*r;        }        public float test(Point3f start, Vector3f dir, float nearestDist) {            // first check, if any intersection with the triangle can result in a nearer result            if(testForIntersection(start,dir)) { // if this is possible, check if there is an intersection with the triangle                // if there is an intersection calculate the exact position                float r = intersect(start,dir);                return(r);            }            return(-1);        }    }`

 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  85 `public class PickResult implements Comparable{    VObject vobject;    Shape3D l;    Point3f pos = null;    Point3f direction = null;    Point3f origin = null;    float distance;    Transform3D temp;    Vector3f tvec;    /** Creates a new instance of PickResult */    public PickResult(VObject v, Shape3D l, float dist) {        vobject = v;        this.l = l;        distance = dist;        temp = new Transform3D();        tvec = new Vector3f();    }        public VObject getVObject() {        return(vobject);    }        public Geometry getGeom() {        return(l.getGeometry());    }        public void transform(Vector3f v) {        l.getLocalToVworld(temp);        temp.invert();        temp.transform(v);    }        public void transform(Point3f p) {        l.getLocalToVworld(temp);        temp.invert();        temp.transform(p);    }        public Point3f getPos() {        return(pos);    }        public void setPos(Point3f p) {        pos = p;    }        public float getDistance() {        return(distance);    }        public void setDistance(float f) {        distance = f;    }        public Vector3f getRayDir() {        return(null);    }        public Point3f getRayStart() {        return(null);    }        public String toString() {        return(vobject+": Leaf: "+l+" Pos:"+pos);    }        public int compareTo(Object o) {        if(o instanceof PickResult) {            PickResult r = (PickResult) o;            if(distance - r.distance > 0) return(1);            if(distance - r.distance < 0) return(-1);        }        return(0);    }        public boolean equals(Object o) {        if(o instanceof PickResult) {            PickResult r = (PickResult) o;            if(r.vobject == vobject && r.l == l && r.pos == pos && r.direction == direction) {                return(true);            }        }        return(false);    }}`

Please note, that there is still need to improvement, and it also works only for Trianglearrays.

:: JOODE :: Xith3d :: OdeJava ::
Amos Wenger

Senior Devvie

Everything's possible, but not everything's fun...

 « Reply #22 - Posted 2005-05-07 07:39:42 »

You can also include it in Gamma, arne.

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #23 - Posted 2005-05-10 11:31:31 »

Yeah, but it's not even a java class it's just a function, but I think I could encapsulate it in a class. But I think it should then go to xith-tk anyways.

:: JOODE :: Xith3d :: OdeJava ::
Amos Wenger

Senior Devvie

Everything's possible, but not everything's fun...

 « Reply #24 - Posted 2005-05-10 15:04:47 »

You're right. ( in fact, we should merge jogl, xith3d, odejava in gamma   ).
You can include it in the org.magicspark.gamma.util.Util class. It's made for that !

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
aNt

Senior Devvie

AFK

 « Reply #25 - Posted 2005-05-12 09:34:15 »

arne thanks dude...
aNt

Senior Devvie

AFK

 « Reply #26 - Posted 2005-05-20 14:42:30 »

VObject? is it the View? or somthing? also the lines:
 1  2  3  4  5  6 `Bounds b = n.getVworldBounds();   result = false;   nopos = false;   if(b instanceof Sphere) result = ((Sphere) b).rayIntersection(o, d, pos);   else if(b instanceof Box) result = ((Box) b).rayIntersection(o, d, pos);   else if(b instanceof ConvexHull) result = ((ConvexHull) b).rayIntersection(o, d, pos);`

n.getVworldBounds(); returns a BoundingSphere not
a Bounds.. so that doesnt compile so i changed it.

All the if elses dont work because its a BoundingSphere
so there not all needed. At this point. not sure if u are
using other packages here.

 1 `if(n instanceof Shape3D) intersecting.add(new PickResult(c.getVObject(),(Shape3D) n, dist));`

no joy at all because i dont no what a VObject is...
c.getVObject()? whats 'c'?
arne

Senior Devvie

money is the worst drug- we should not let it rule

 « Reply #27 - Posted 2005-05-20 15:33:23 »

You can remove the VObject stuff, because that's just something I use for my Game (to know which Object got picked and not only the Shape) - I thought I removed everything of this stuff, when I posted the code.

Quote
n.getVworldBounds(); returns a BoundingSphere not
a Bounds.. so that doesnt compile so i changed it.

Oh yeah you're right. n.getBounds() returns Bounds(), so I  probably just had Bounds there  because I used getBounds() before which was wrong and I haven't noticed, that it changed to BoundingSphere when I corrected it.
But it should work anyways: BoundingSphere implements Bounds. That's simply in com.xith3d.scenegraph. BoundingSphere extends Sphere in com.xith3d.spatial.bounds. So it should work, but your's is simpler.

+ you will have to move all this instance creating out of this, if you want to use it frequently, so this will leave you with a lot of temporary variables.

If you have questions don't bother asking!!

Arne

:: JOODE :: Xith3d :: OdeJava ::
Amos Wenger

Senior Devvie

Everything's possible, but not everything's fun...

 « Reply #28 - Posted 2005-12-07 17:44:45 »

THANKS A LOT ARNE !!!

It's so wonderful ! After a few minutes trying to understand something to the Picking posts in the JOGL/LWJGL sections, I remembered you had made some code and rushed on it.
I adapted it a bit :
- I removed the VObject stuff entirely
- I put it in a class (GraphicUtils, in Gamma)
- I made it use the Triangle3D class in Gamma (and added your functions to this class)
You can take a look at the code in the SVN repository.
I'm actually making a pre-"level editor" (for now it's just a test for the line intersection test in 2D).

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 ClaasJG (29 views) 2015-04-27 13:36:51 BurntPizza (34 views) 2015-04-23 03:42:11 theagentd (37 views) 2015-04-22 16:23:07 Riven (51 views) 2015-04-16 10:48:47 Duke0200 (60 views) 2015-04-16 01:59:01 Fairy Tailz (43 views) 2015-04-14 20:13:12 Riven (47 views) 2015-04-12 21:36:37 bus hotdog (65 views) 2015-04-10 02:39:32 CopyableCougar4 (67 views) 2015-04-10 00:51:04 BurntPizza (72 views) 2015-04-06 22:06:58
 theagentd 23x BurntPizza 17x wessles 15x Spasi 12x 65K 11x kingroka123 11x alwex 11x Rayvolution 7x Hanksha 7x Riven 7x chrislo27 7x kevglass 7x Olo 7x Ecumene 7x ra4king 7x KevinWorkman 6x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 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