У меня есть координаты мыши: mousePos, матричный вид view и матрица перспективной проекции pMatrix.
Я перевожу координаты в мир: нахожу матрицу обратной проекции и вид обратной матрицы и умножаю на координаты мыши. Координаты начала z = 4, конца z = -100.
В первом случае я получаю координаты mouseDir1 = (-0.1985 0.02887 4), а во втором - mouseDir2 = (-0.1985 0.02887 -100).
Почему координаты x, y совпадают?
private Vector3f getCoord(MouseInput mouseInput,float z){
int wdwWitdh = 640;
int wdwHeight =640;
Vector2d mousePos = mouseInput.getCurrentPos();
float x = (float)(2 * mousePos.x) / (float)wdwWitdh - 1.0f;
float y = 1.0f - (float)(2 * mousePos.y) / (float)wdwHeight;
Matrix4f invProjectionMatrix = new Matrix4f();
invProjectionMatrix.set(pMatrix);
invProjectionMatrix.invert();
Vector4f tmpVec = new Vector4f();
tmpVec.set(x, y, z, 0);
tmpVec.mul(invProjectionMatrix);
tmpVec.z = z;
tmpVec.w = 0.0f;
Matrix4f viewMatrix = new Matrix4f().set(view);
Matrix4f invViewMatrix = new Matrix4f();
invViewMatrix.set(viewMatrix);
invViewMatrix.invert();
tmpVec.mul(invViewMatrix);
Vector3f mouseDir1 = new Vector3f();
mouseDir1.set(tmpVec.x, tmpVec.y, tmpVec.z);
///ТЕСТОВАЯ ПРОВЕРКА Z=-100;
//конеч координаты луча
Vector4f tmpVec1 = new Vector4f();
tmpVec1.set(x, y, -100, 1.0f);
tmpVec1.mul(invProjectionMatrix);
tmpVec1.z =-100f;
tmpVec1.w = 0.0f;
tmpVec1.mul(invViewMatrix);
Vector3f mouseDir2 = new Vector3f();
mouseDir2.set(tmpVec1.x, tmpVec1.y, tmpVec1.z);
System.out.println();
return mouseDir1;
}
@AxelH Я знаю. Проблема не в этом.
В чем ценность pMatrix?
@AxelH Matrix4f p = новый Matrix4f (). Перспектива ((float) Math.toRadians (60.0f), 640f / 640f, 0.01f, 1000.0f); частный FloatBuffer pMatrix = BufferUtils.createFloatBuffer (16);




В общем, вы должны использовать Matrix4f.unproject, так как @httpdigest продемонстрировал в своем ответе.
Итак, я хочу сосредоточиться на фоне:
Why are the coordinates x, y the same?
Координаты одинаковы, потому что координаты x и y источника одинаковы, и вы не делите перспективу после умножения на матрицу обратной проекции. Операция mul не выполняет разделения перспективы, она преобразует Vector4f в Matrix4f, и в результате также получается тип Vector4f.
Кроме того, исходные координаты, которые вы умножаете на матрицу обратной проекции, должны быть нормализованными координатами устройства, где x, y и z находятся в диапазоне [-1,0, 1,0]. z=-1.0 - это минимальная глубина (ближняя плоскость), а z=1.0 - максимальная глубина (дальней плоскость).
Примечание: проекция линии обзора (луча обзора) на область просмотра, конечно же, является точкой.
Когда вы выполняете умножение на матрицу (обратной) проекции, результатом будет не Декартовы координаты, а Однородные координаты. Вы должны выполнить Перспективный разрыв для преобразования однородных координат в декартовы координаты:
// transform x and y mouse coordinate to normalized device space
Vector2d mousePos = mouseInput.getCurrentPos();
float x = (float)(2 * mousePos.x) / (float)wdwWitdh - 1.0f;
float y = 1.0f - (float)(2 * mousePos.y) / (float)wdwHeight;
....
// normalized device coordinate to view space coordinate (near plane)
Vector4f tmpVec = new Vector4f();
tmpVec.set(x, y, -1.0f, 1.0f);
tmpVec.mul(invProjectionMatrix);
// perspective divide
tmpVec.x = tmpVec.x / tmpVec.w;
tmpVec.y = tmpVec.y / tmpVec.w;
tmpVec.z = tmpVec.z / tmpVec.w;
tmpVec.w = 1.0;
// normalized device coordinate to view space coordinate (far plane)
Vector4f tmpVec1 = new Vector4f();
tmpVec1.set(x, y, 1.0f, 1.0f);
tmpVec1.mul(invProjectionMatrix);
// perspective divide
tmpVec1.x = tmpVec1.x / tmpVec1.w;
tmpVec1.y = tmpVec1.y / tmpVec1.w;
tmpVec1.z = tmpVec1.z / tmpVec1.w;
tmpVec1.w = 1.0;
Матрица проекции описывает сопоставление трехмерных точек сцены с двухмерными точками области просмотра. Матрица проекции преобразуется из пространства просмотра в пространство клипа. Координаты в пространстве клипа преобразуются в нормализованные координаты устройства (NDC) в диапазоне от (-1, -1, -1) до (1, 1, 1) путем деления на компонент w координат клипа.
В Perspective Projection матрица проекции описывает отображение трехмерных точек мира, видимых из камеры-обскуры, с двухмерными точками окна просмотра.
Координаты пространства глаз в усеченной пирамиде камеры отображаются в куб (нормализованные координаты устройства).
Из-за этого координаты x и y в окне просмотра зависят от глубины (координата z пространства просмотра).
Vector3f worldCoords = new Matrix4f (pMatrix) .mul (view) .unproject (new Vector3f (x, y, z), new int [] {0, 0, wdwWidth, wdwHeight}, new Vector3f ());
@ Rabbid76 Я бы не хотел, чтобы вы удаляли свой ответ, потому что я считаю его отличным, поскольку он объясняет предысторию.
Библиотека матриц, которую вы, кажется, используете, JOML, предоставляет эту операцию (которая обычно называется «спроецирование») с помощью следующего кода (адаптированного к вашему коду):
Vector3f worldCoords = new Matrix4f(pMatrix).mul(view).unproject(x, y, z,
new int[] { 0, 0, wdwWidth, wdwHeight }, new Vector3f());
Все время в центре отображается
«Все время в центре отображается» - что?
Луч находится в центре.
Вы возвращаете
mouseDir1вместоmouseDir2, который вы использовали для хранения результата вектора.