简体   繁体   English

关于 3D 在 Android 中拣货的问题(使用 OpenGL ES 2)

[英]Question about 3D Picking in Android (with OpenGL ES 2)

I need some help on 3D picking.我需要一些关于 3D 挑选的帮助。

I am using the way it works here .我正在使用它 在这里的工作方式。 In short, what I have is:简而言之,我所拥有的是:

normalizedPoint[0] = (x * 2 / screenW) -1;
normalizedPoint[1] = 1 - (y * 2 / screenH);
normalizedPoint[2] = ?
normalizedPoint[3] = ?

for 2 and 3, I have no idea what it should be (I put 1, -1 just like the reference, and it doesn't work)对于 2 和 3,我不知道它应该是什么(我把 1,-1 就像参考一样,它不起作用)

Then, for my root object (following just psuedo code):然后,对于我的根 object(仅遵循伪代码):

matrix = perspective_matrix x model_matrix
inv_matrix = inverse(matrix)
outpoint = inv_matrix x normalizedPoint

That's what I have, but it doesn't work, the outPoint I receive is not even close to the point I am suppose clicking.这就是我所拥有的,但它不起作用,我收到的 outPoint 甚至不接近我想点击的点。 I've been searching in web for more than a week.我已经在 web 中搜索了一个多星期。 but no idea how to solve it.但不知道如何解决它。 HELP!帮助!

Oh.哦。 I actually solved the problem, sort of.我实际上解决了这个问题,有点。

I first, modify from the source code of glUnproject to have the following:我首先从 glUnproject 的源代码修改为具有以下内容:

public static Vec3 unProject(
        float winx, float winy, float winz,
        Matrix44 resultantMatrix,
        int width, int height){
    float[] m = new float[16],
    in = new float[4],
    out = new float[4];

    m = Matrix44.invert(resultantMatrix.get());

    in[0] = (winx / (float)width) * 2 - 1;
    in[1] = (winy / (float)height) * 2 - 1;
    in[2] = 2 * winz - 1;
    in[3] = 1;

    Matrix.multiplyMV(out, 0, m, 0, in, 0);

    if (out[3]==0)
        return null;

    out[3] = 1/out[3];
    return new Vec3(out[0] * out[3], out[1] * out[3], out[2] * out[3]);
}

Input to the above would be the point in the Projected View Frustum Coordinates (ie, screen input).上面的输入将是投影视图平截头体坐标中的点(即屏幕输入)。 For example:例如:

unProject(30, 50, 0, mvpMatrix, 800, 480) 

will translate the screen input (click) at (30,50) to the world coordinate where the object is sitting at.将 (30,50) 处的屏幕输入(点击)转换为 object 所在的世界坐标。 The third parameter, winz is actually on which projected plane the click is occured, here, 0 means the nearZ of the projection plane.第三个参数winz其实就是点击发生在哪个投影平面上,这里的0表示投影平面的nearZ。

The way I make picking functions, is by unprojecting two points, using the above function, on the far and near clipping plane, so:我制作拾取功能的方式是使用上述 function 在远近剪裁平面上取消投影两个点,因此:

Vec3 near = unProject(30, 50, 0, mvpMatrix, 800, 480);
Vec3 far = unProject(30, 50, 1, mvpMatrix, 800, 480);   // 1 for winz means projected on the far plane
Vec3 pickingRay = Subtract(far, near); // Vector subtraction

Once we have the picking ray, what I am doing is simply testing the distance between the picking ray and the "center" of those "pickable" objects.一旦我们有了拾取射线,我所做的只是测试拾取射线与那些“可拾取”对象的“中心”之间的距离。 (of course, you can have some more sophisticated testing algorithm). (当然,你可以有一些更复杂的测试算法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM