从归一化设备坐标计算世界坐标
Calculate World Coordinates from Normalized Device Coordinates
我目前正在尝试在世界 Space 的屏幕上注册触摸。
我首先将它们转换为规范化的设备坐标,然后尝试将规范化立方体近侧的一个点 (z = -1) 和规范化立方体远侧的一个点 (z = 1) 与倒置的 ProjectionViewMatrix 相乘在他们之间划一条线。
到目前为止我的方法:
//Calculate ProjectionViewMatrix
Matrix.multiplyMM(projectionViewMatrix,0,perspectiveProjectionMatrix,0,viewMatrix,0);
//Calculate Inverse
Matrix.invertM(invertedProjectionViewMatrix,0,projectionViewMatrix,0);
float[] nearPoint = {x, y, -1, 1};
float[] farPoint = {x, y, 1, 1};
float[] nearPointWorldSpace = new float[4];
float[] farPointWorldSpace = new float[4];
Matrix.multiplyMV(nearPointWorldSpace,0, invertedProjectionViewMatrix,0, nearPoint,0);
Matrix.multiplyMV(farPointWorldSpace,0, invertedProjectionViewMatrix,0, farPoint,0);
perspectiveDevide(nearPointWorldSpace);
perspectiveDevide(farPointWorldSpace);
其中 perspectiveDevide 定义为:
private static void perspectiveDevide(float[] vector) {
vector[0] /= vector[3];
vector[1] /= vector[3];
vector[2] /= vector[3];
}
现在我应该得到的是具有相同或非常相似的近点和远点X/Y-Coordinates,因为我的相机在 lookAt 的正上方并且没有角度。
但是我得到的是:
近点世界:
[0] -0.002805814
[1] 0.046295937
[2] 1.9
[3] 9.999999
远点世界:
[0] -2.8057494
[1] 46.294872
[2] -97.99771
[3] 0.010000229
任何想法可能有什么问题?
编辑:
这是我的视图和投影矩阵代码:
投影:
Matrix.perspectiveM(perspectiveProjectionMatrix,0, 60, (float) width / (float) height, 0.1f, 100f);
查看:
Matrix.setLookAtM(viewMatrix,0,
0,0,2,
0,0,0,
0,1,0);
正如 Nico Schertler 所指出的,这些结果实际上是合理的。
为了获得正确的 X/Y 坐标,我不得不取消投影屏幕中心。
我目前正在尝试在世界 Space 的屏幕上注册触摸。 我首先将它们转换为规范化的设备坐标,然后尝试将规范化立方体近侧的一个点 (z = -1) 和规范化立方体远侧的一个点 (z = 1) 与倒置的 ProjectionViewMatrix 相乘在他们之间划一条线。 到目前为止我的方法:
//Calculate ProjectionViewMatrix
Matrix.multiplyMM(projectionViewMatrix,0,perspectiveProjectionMatrix,0,viewMatrix,0);
//Calculate Inverse
Matrix.invertM(invertedProjectionViewMatrix,0,projectionViewMatrix,0);
float[] nearPoint = {x, y, -1, 1};
float[] farPoint = {x, y, 1, 1};
float[] nearPointWorldSpace = new float[4];
float[] farPointWorldSpace = new float[4];
Matrix.multiplyMV(nearPointWorldSpace,0, invertedProjectionViewMatrix,0, nearPoint,0);
Matrix.multiplyMV(farPointWorldSpace,0, invertedProjectionViewMatrix,0, farPoint,0);
perspectiveDevide(nearPointWorldSpace);
perspectiveDevide(farPointWorldSpace);
其中 perspectiveDevide 定义为:
private static void perspectiveDevide(float[] vector) {
vector[0] /= vector[3];
vector[1] /= vector[3];
vector[2] /= vector[3];
}
现在我应该得到的是具有相同或非常相似的近点和远点X/Y-Coordinates,因为我的相机在 lookAt 的正上方并且没有角度。 但是我得到的是:
近点世界:
[0] -0.002805814
[1] 0.046295937
[2] 1.9
[3] 9.999999
远点世界:
[0] -2.8057494
[1] 46.294872
[2] -97.99771
[3] 0.010000229
任何想法可能有什么问题?
编辑:
这是我的视图和投影矩阵代码:
投影:
Matrix.perspectiveM(perspectiveProjectionMatrix,0, 60, (float) width / (float) height, 0.1f, 100f);
查看:
Matrix.setLookAtM(viewMatrix,0,
0,0,2,
0,0,0,
0,1,0);
正如 Nico Schertler 所指出的,这些结果实际上是合理的。 为了获得正确的 X/Y 坐标,我不得不取消投影屏幕中心。