получить мышь в мировых координатах с помощью 2 вызовов gluUnproject для создания луча

Я пытаюсь использовать то, что многие люди, кажется, находят хорошим способом, я вызываю gluUnproject 2 раза с разными z-значениями, а затем пытаюсь вычислить вектор направления для луча из этих двух векторов.

Я прочитал этот вопрос и попытался использовать эту структуру для своего собственного кода:

        glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
        glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
        glGetInteger(GL_VIEWPORT, viewBuffer);

        gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
        gluUnProject(mouseX, mouseY, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);

        start = vecmath.vector(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
        end = vecmath.vector(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));

        direction = vecmath.vector(end.x()-start.x(), end.y()-start.y(), end.z()-start.z());

Но это возвращает только однородные координаты клипа (я считаю), поскольку они варьируются только от -1 до 1 по каждой оси.

Как на самом деле получить координаты, по которым я могу создать луч?

РЕДАКТИРОВАТЬ: Вот как я строю матрицы:

Matrix projectionMatrix = vecmath.perspectiveMatrix(60f, aspect, 0.1f,
            100f);
//The matrix of the camera = viewMatrix
setTransformation(vecmath.lookatMatrix(eye, center, up));
//And every object sets a ModelMatrix in it's display method  
Matrix modelMatrix = parentMatrix.mult(vecmath
                    .translationMatrix(translation));
modelMatrix = modelMatrix.mult(vecmath.rotationMatrix(1, 0, 1, angle));

ИЗМЕНИТЬ 2:

Вот так функция выглядит сейчас:

private void calcMouseInWorldPosition(float mouseX, float mouseY, Matrix proj, Matrix view) {
    Vector start = vecmath.vector(0, 0, 0);
    Vector end = vecmath.vector(0, 0, 0);

    FloatBuffer modelBuffer = BufferUtils.createFloatBuffer(16);
    modelBuffer.put(view.asArray());
    modelBuffer.rewind();
    FloatBuffer projBuffer = BufferUtils.createFloatBuffer(16);
    projBuffer.put(proj.asArray());
    projBuffer.rewind();

    FloatBuffer startBuffer = BufferUtils.createFloatBuffer(16);
    FloatBuffer endBuffer = BufferUtils.createFloatBuffer(16);
    IntBuffer viewBuffer = BufferUtils.createIntBuffer(16);

     //The two calls for projection and modelView matrix are disabled here,   
       as I use my own matrices in this case
//  glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
//  glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
    glGetInteger(GL_VIEWPORT, viewBuffer);

    //I know this is really ugly and bad, but I know that the height and width is always 600  
    // and this is just for testing purposes 
    mouseY = 600 - mouseY;

    gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
    gluUnProject(mouseX, mouseY, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);

    start = vecmath.vector(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
    end = vecmath.vector(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));

    direction = vecmath.vector(end.x()-start.x(), end.y()-start.y(), end.z()-start.z());

}

Я пытаюсь использовать свою собственную матрицу проекции и вида, но это дает только более странные результаты.
С помощью GlGet ... я получаю это, щелкнув в правом верхнем углу:
начало: (0,97333336, -0,98, -1,0)
конец: (0,97333336, -0,98, 1,0)

Когда я использую свои собственные материалы, я получаю это для той же позиции:
start: (-2.4399707, -0.55425626, -14.202201)
end: (-2.4399707, -0.55425626, -16.198204)

Теперь мне действительно нужна матрица modelView, а не просто матрица представления, но я не знаю, как мне ее получить, поскольку она изменяется и создается заново при каждом вызове отображения каждого объекта.
Но действительно ли это эта проблема? В этом руководстве он говорит: «Обычно, чтобы попасть в пространство клипа из глазного пространства, мы умножьте вектор на матрицу проекции. Мы можем вернуться назад, умножив на обратную матрицу ». и на следующем шаге он снова умножит на обратную матрицу вида, поэтому я подумал, что это то, что я должен на самом деле делать?

ИЗМЕНИТЬ 3:
Здесь я попробовал то, что предложил user42813:

    Matrix view = cam.getTransformation();
    view = view.invertRigid();

    mouseY = height - mouseY - 1;

    //Here I only these values, because the Z and W values would be 0  
    //following your suggestion, so no use adding them here
    float tempX = view.get(0, 0) * mouseX + view.get(1, 0) * mouseY;
    float tempY = view.get(0, 1) * mouseX + view.get(1, 1) * mouseY;
    float tempZ = view.get(0, 2) * mouseX + view.get(1, 2) * mouseY;

    origin = vecmath.vector(tempX, tempY, tempZ);
    direction = cam.getDirection();

Но теперь значения направления и исходной точки всегда одинаковы:
origin: (-0.04557252, -0.0020000197, -0.9989586)
direction: (-0.04557252, -0.0020000197, -0.9989586)


person Big_Chair    schedule 19.09.2014    source источник
comment
gluUnProject предполагается полностью вернуться к координатам пространства объекта. Скорее всего, у вас есть идентификационная матрица ModelView / Projection. На какую версию GL вы нацеливаетесь? Я легко могу увидеть glGetFloat (...) возврат неинициализированных матриц, например, если вы используете ядро ​​GL 3.2. В этом случае будет определено только окно просмотра, и это объяснит, почему вы возвращаетесь только в пространство клипа.   -  person Andon M. Coleman    schedule 19.09.2014
comment
@ AndonM.Coleman Моя версия - 3.1.0.   -  person Big_Chair    schedule 19.09.2014
comment
Является ли GL_ARB_compatibility одним из расширений в строке расширений? Более того, если вы строите матрицы с использованием отдельной библиотеки, почему вы пытаетесь запрашивать их из OpenGL?   -  person Andon M. Coleman    schedule 19.09.2014
comment
@ AndonM.Coleman Извините, я не знаю, что означает строка расширения. И хорошо, я не знаю, как еще я должен получить необходимые матрицы для метода gluUnproject, особенно modelMatrix, поскольку он изменяется с каждым объектом. Я мог бы каким-то образом получить там матрицы вида и проекции, но мне все еще нужна матрица ModelView и как я должен ее создать / получить?   -  person Big_Chair    schedule 19.09.2014
comment
@ AndonM.Coleman Да, прямо сейчас я пробовал делать modelBuffer.put (view.asArray ()); projBuffer.put (proj.asArray ()); Но я могу использовать только матрицу вида и проекции, на данный момент я не могу получить матрицу модели. Поэтому я использовал матрицу представления вместо modelView. Но это, похоже, не работает ...   -  person Big_Chair    schedule 20.09.2014
comment
К сожалению, вам придется объяснить свою ситуацию немного яснее (в вашем вопросе, потому что эти комментарии превращаются в беспорядок). Я даже не уверен, используете ли вы сейчас конвейер с фиксированной функцией или шейдер. Но если у вас есть матрица просмотра, вы можете просто умножить ее на матрицу модели вашего объекта, чтобы получить матрицу просмотра модели. В любом случае, если бы это действительно работало (матрица модели без), это было бы в мировом пространстве, а не в пространстве клипа, как вы описывают: - \   -  person Andon M. Coleman    schedule 20.09.2014
comment
@ AndonM.Coleman Да, я обновил свой вопрос, надеюсь, это поможет прояснить некоторые вещи   -  person Big_Chair    schedule 20.09.2014


Ответы (2)


Хорошо, мне наконец удалось это решить, может быть, это кому-то поможет.
Я нашел для этого некую формулу и сделал это с координатами, которые я получал, которые варьировались от -1 до 1:

    float tempX = (float) (start.x() * 0.1f * Math.tan(Math.PI * 60f / 360));
    float tempY = (float) (start.y() * 0.1f * Math.tan(Math.PI * 60f / 360) * height / width);
    float tempZ = -0.1f;

    direction = vecmath.vector(tempX, tempY, tempZ); //create new vector with these x,y,z
    direction = view.transformDirection(direction); 
    //multiply this new vector with the INVERSED viewMatrix
    origin = view.getPosition(); //set the origin to the position values of the matrix (the right column)
person Big_Chair    schedule 26.09.2014

Я на самом деле не использую устаревший opengl, но я хотел бы поделиться своей мыслью. Во-первых, было бы полезно, если бы вы показали нам, как вы строите свою матрицу просмотра. Во-вторых, матрица просмотра, которая у вас есть, находится в локальном пространстве камеры, теперь обычно вы бы умножили свой mouseX и (ScreenHeight - mouseY - 1) матрицей View (я думаю, что это обратная матрица, извините, не уверен!), тогда у вас будут координаты мыши в пространстве камеры, затем вы добавите вектор Forward к этому вектору, созданному мышь, то она у вас будет, она будет выглядеть примерно так:

float mouseCoord[] = { mouseX, screen_heihgt - mouseY - 1, 0, 0 }; /* 0, 0 because we multipling by a matrix 4.*/
mouseCoord = multiply( ViewMatrix /*Or: inverse(ViewMatrix)*/, mouseCoord );
float ray[] = add( mouseCoord, forwardVector );
person Mehdi    schedule 19.09.2014
comment
что из моего кода устарело? Методы glGetxxx ()? Каковы были бы современные способы этого? - person Big_Chair; 19.09.2014
comment
gluPerspective (..), gluUnProject (...), glMatrixMode (..), glTranslateX (..), glRotateX (..), ... ну, современным способом будет создание вашей собственной математической библиотеки, или используя уже определенный, например, glm, если вы используете C / C ++ или взгляните на математическую библиотеку LibGDX, она отличная, вам также нужно использовать шейдеры без gl_ModelViewMatrix / gl_NormalMatrix / gl_Vertex ..., и список идет во-первых, вы можете иметь здесь несколько отличных слов, ссылка, также обратите внимание, что если предоставленный мной код работает, тогда луч будет в пространстве камеры. - person Mehdi; 20.09.2014
comment
о коде, который вы предоставляете, обратите внимание, что хорошая идея создавать директивные буферы в каждом кадре, что вы должны сделать, это создать статические ссылки и повторно использовать их. - person Mehdi; 20.09.2014
comment
Еще одна вещь: если вы используете мышь для управления вращением камеры, тогда код упрощается до (ray = cameraForward). - person Mehdi; 20.09.2014
comment
Я отредактировал свой вопрос и попробовал то, что вы предложили. но на самом деле это не сработало: / - person Big_Chair; 20.09.2014