【问题标题】:How to map 2D display coordinate to 3D OpenGL space如何将 2D 显示坐标映射到 3D OpenGL 空间
【发布时间】:2013-06-28 09:00:11
【问题描述】:

我正在开发一款移植到 Android 上的 3D 游戏,我想在游戏的 3D 过程中处理触摸事件。我需要 3D 空间中的点,就在剪裁平面附近,但我能得到的只是来自 Android 显示器的 2D 坐标。那么,有没有办法将这些(x,y)坐标映射到3D空间中的(x,y,z)坐标?

编辑

嗯,我正在开发一款赛车游戏,我想在课程中插入一些项目,具体取决于我单击的位置。我有这个功能:

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);
}

但现在我将物品插入玩家面前一段距离:

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);
    .
    .
    .
}

,但是如何将其转换为显示表面,我一无所知。

【问题讨论】:

标签: android c opengl-es 3d coordinate-transformation


【解决方案1】:

要将 2D 显示坐标 (display_x, display_y) 重新映射到 3D 对象坐标 (x,y,z) 您需要知道

  1. (display_x, display_y)处像素的深度display_z
  2. 将剪辑空间坐标(clip_x, clip_y, clip_z) 转换为显示坐标的转换T
  3. M 将对象坐标转换为剪辑空间坐标的转换(通常结合了相机和透视图)

显示坐标计算如下

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 是任何可逆变换。

您可以从(display_x, display_y, display_z) 恢复(x,y,z),如下所示

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)

下面给出了为什么上述计算会导致正确的解决方案的直觉

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)属性:

M * (a * v) == a * (M * v)

【讨论】:

    猜你喜欢
    • 2017-04-19
    • 2021-05-05
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 2015-06-29
    • 1970-01-01
    • 2014-05-06
    相关资源
    最近更新 更多