如何将 2D 显示坐标映射到 3D OpenGL 空间 [英] How to map 2D display coordinate to 3D OpenGL space
问题描述
我正在开发一款移植到 Android 上的 3D 游戏,我想在游戏的 3D 过程中处理触摸事件.我需要 3D 空间中的点,就在剪裁平面附近,但我所能得到的只是来自 Android 显示器的 2D 坐标.那么,有什么办法可以将这些 (x, y) 坐标映射到 3D 空间中的 (x, y, z) 坐标吗?
I am working on a 3D game that is ported on Android and I want to work with touch events in 3D course of a game. I need point in 3D space, right on near clipping plane, but all I can get is a 2D coordinates from an Android display. So, is there any way to map these (x, y) coordinates to (x, y, z) coordinates in 3D space?
嗯,我正在开发一款赛车游戏,我想在课程中插入一些项目,具体取决于我点击的位置.我有这个功能:
Well, I am working on a racing game, and I want to insert some items on a course, depending on where I click. I have this function:
void racing_mouse_cb(int button, int state, int x, int y) { //parameters (x,y) are coords of a display
set_ill_fish(get_player_data( local_player())->view);
}
但现在我是在玩家面前一定距离插入物品:
but for now I am inserting items in front of a player at some distance:
void set_ill_fish(view_t view) {
item_locs[num_items].ray.pt.x = view.plyr_pos.x;
item_locs[num_items].ray.pt.z = view.plyr_pos.z - 5;
item_locs[num_items].ray.pt.y = find_y_coord(view.plyr_pos.x,
view.plyr_pos.z - 5) + 0.2;
item_locs[num_items].ray.vec = make_vector(0, 1, 0);
.
.
.
}
,但是如何将其转换为显示面,我一无所知.
, but how to translate this to display surface, I am clueless.
推荐答案
重新映射 2D 显示坐标 (display_x, display_y)
到 3D 对象坐标 (x,y,z)代码>你需要知道
To remap 2D display coordinates (display_x, display_y)
to 3D object coordinates (x,y,z)
you need to know
(display_x, display_y)
处像素的深度- transformation
T
将裁剪空间坐标(clip_x, clip_y, clip_z)
转换为显示坐标 - 转换
M
将对象坐标转换为裁剪空间坐标(通常结合相机和透视图)
display_z
- the depth
display_z
of the pixel at(display_x, display_y)
- the transformation
T
that transforms clip space coordinates(clip_x, clip_y, clip_z)
to display coordinates - the transformation
M
that transforms object coordinates to clip space coordinates (usually combines a camera and a perspective)
显示坐标计算如下
M.transform(x, y, z, 1) --> (clip_x, clip_y, clip_z, clip_w)
T.transform(clip_x / clip_w, clip_y / clip_w, clip_z / clip_w) --> (display_x, display_y, display_z)
M.transform
是可逆矩阵乘法,T.transform
是任何可逆变换.
M.transform
is an invertible matrix multiplication and T.transform
is any invertible transformation.
你可以从 (display_x, display_y, display_z)
恢复 (x,y,z)
如下
You can recover (x,y,z)
from (display_x, display_y, display_z)
as follows
T.inverse_transform(display_x, display_y, display_z) --> (a, b, c)
M.inverse_transform(a, b, c, 1) --> (X, Y, Z, W)
(X/W, Y/W, Z/W) --> (x, y, z)
以下给出了为什么上述计算会导致正确解决方案的直觉
The following gives intuition on why the above computation leads to the right solution
T.inverse_transform(display_x, display_y, display_z) --> (clip_x / clip_w, clip_y / clip_w, clip_z / clip_w)
(clip_x / clip_w, clip_y / clip_w, clip_z / clip_w, clip_w / clip_w) == (clip_x, clip_y, clip_z, clip_w) / clip_w
M.inverse_transform((clip_x, clip_y, clip_z, clip_w) / clip_w) == M.inverse_transform(clip_x, clip_y, clip_z, clip_w) / clip_w
M.inverse_transform(clip_x, clip_y, clip_z, clip_w) / clip_w --> (x, y, z, 1) / clip_w
(x, y, z, 1) / clip_w == (x / clip_w, y / clip_w, z / clip_w, 1 / clip_w)
(x / clip_w, y / clip_w, z / clip_w, 1 / clip_w) == (X, Y, Z, W)
上面使用了以下矩阵 (M
) 向量 (v
) 标量 (a == 1/clip_w
) 属性:>
The above used the following matrix (M
) vector (v
) scalar (a == 1 / clip_w
) property:
M * (a * v) == a * (M * v)
这篇关于如何将 2D 显示坐标映射到 3D OpenGL 空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!