pick ray

How I can get a pick ray in ortografic projection?.
The solutions what I can see in this forum don´t work.
The XITH3D Api should solucione this problem.
please help me.

The idea is to first determine the world-space view plane coordinates of the pick and then cast a ray from that location along the view vector.

Here’s my pick ray code:

public void createPickRay(int x, int y, Point3f o, Vector3f d) {
float rx = (float)x/(float)getWidth() - 0.5f;
float ry = 1.0f - (float)y/(float)getHeight() - 0.5f;
float px = rxphysicalWidth;
float py = ry
physicalHeight;
float vpd = camera.getViewPlaneDistance();
if (camera.getPerspective()) {
o.set(0.0f, 0.0f, 0.0f);
d.set(px, py, -vpd);
d.normalize();
}
else {
float s = camera.getScale();
o.set(px/s, py/s, 0.0f);
d.set(0.0f, 0.0f, -1.0f);
}

view.getTransform(t1);
t1.transform(o);
t1.transform(d);
}

should this method be added to the core?

Will.

Uh… what’s a pick ray?

yes yes yes +2

There is a problem,
Where is Camera class?

The code I posted requires maintaining the physical width and height of the window on the monitor. This code should also work (though I haven’t tested it):

public void createPickRay(int x, int y, Point3f o, Vector3f d) {
float rx = (float)x/(float)getWidth() - 0.5f;
float ry = 1.0f - (float)y/(float)getHeight() - 0.5f;
float vpd = 0.5f/(float)Math.tan(view.getFieldOfView());
if (view.getProjectionPolicy() == View.PERSPECTIVE_PROJECTION ) {
o.set(0.0f, 0.0f, 0.0f);
d.set(rx, ry, -vpd);
d.normalize();
}
else {
o.set(rx, ry, 0.0f);
d.set(0.0f, 0.0f, -1.0f);
}

view.getTransform(t1);
t1.transform(o);
t1.transform(d);
}

I am working with a collision system (as you maybe already know :)) and maybe one could use this method to maintain a picking intersection?

At least I am working on it.

Alonzo

I don’t use picking myself, so if you want this added to the core, can someone please tell me which class to add it too :slight_smile:

Will.

I think that the code should be in Canvas3D class, but I don´t know
if that code work in orthografic projection, because the function
should work in orthografic and perspective projection.

I think it makes sense to put the method in either Canvas3D or in the CanvasPeerImplS.

OK.

If someone writes a full javadoc comment and some code comments, I shall add it in.

Will.

I’ve just gotten around to testing the most recent code I posted. IT DOESN’T WORK! Sorry guys! The original code utilized a Camera class that adjusts view distance to maintain an accurate screen scale. Removing this dependency is more difficult than I originally thought. Working on a solution now… I’ll post as soon as I figure it out!

Got the code working independently. :smiley: This code requires the most recent Xith from CVS to create correct pick rays for orthographic views. This method should probably be added to Canvas3D to avoid the code repetition necessary for adding the method to the CanvasPeerImplS.

/**

  • Loads a world-space ray pick using the specified pixel location.

  • @param x The x coordinate of the pixel location.

  • @param y The y coordinate of the pixel location.

  • @param o The Point3f that will be loaded with the ray origin.

  • @param d The Vector3f that will be loaded with the ray direction.
    /
    public void createPickRay(int x, int y, Point3f o, Vector3f d) {
    float w = (float)getWidth();
    float h = (float)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(srx, sry, 0.0f);
    d.set(0.0f, 0.0f, -1.0f);
    }

// transform the ray into world space.
view.getTransform().transform(o);
view.getTransform().transform(d);
}

ok, its in.

Will.

I am sorry, but the last code do not work in orthografic projection,
try that, put the eye in (200,200,200) looks to (0,0,0) in a orthografic projection, draw three lines since (0,0,0) to (1,0,0)-(0,1,0)-(0, 0 ,1), the pick ray is easy to calcule,(is direct),
then pick in a end of the line and look the result.
you can see that dont work.

Hi,

I am trying to make an overview of a world, and I want the user to select objects dragging the mouse over it (while pressing the button).

In example:
I click the left mouse at (100, 100) and drag it to (200, 200).
Let’s say the vectors will be (1, 1, -2) and (3, 3, -2) and I have a point, let’s say (0, 0, -10).

The question here is, how do I know the point is inside the selection if the camera is located at (0, 0, 0)?

jcmeira:

I’m not quite sure what to do with your test case. If the camera is at (200, 200, 200) looking at (0, 0, 0) and a click occurs in the center of the window, the pick ray should be (-1, -1, -1) (normalized) from (200, 200, 200) regardless of the projection mode. Can you give me a concrete test case including an object description, object location and orientation, camera position and orientation, window size, and picked pixel location?

DonCrudelis:

It sounds like you want to rubber band an area. I would suggest using the setPickMode and getPickRenderResults methods in CanvasPeerBase