gpt4 book ai didi

c++ - 从相机投影线

转载 作者:搜寻专家 更新时间:2023-10-31 01:24:40 24 4
gpt4 key购买 nike

我正在尝试将视口(viewport)点击转换为对象的世界位置。

如果我只想在用户在 Canvas 中点击的位置精确地绘制一个点,那将非常简单:

void Canvas::getClickPosition(int x, int y, Vector3d(&out)[2]) const
{
Vector4d point4d[2];
Vector2d point2d(x, y);
int w = canvas.width();
int h = canvas.height();
Matrix4d model = m_world * m_camera;

for (int i = 0; i < 2; ++i) {
Vector4d sw(point2d.x() / (0.5 * w) - 1,
point2d.y() / (0.5* h) - 1, i * 1, 1);

point4d[i] = (m_proj * model).inverse() * sw;
out[i] = point4d.block<1, 3>(0, 0);
}
}

预期的行为是通过这个简单的代码实现的。

当我尝试制作一条在用户首次点击时看起来像一个像素 的线条时,问题就出现了。在相机朝任何方向旋转之前,它应该看起来像是从相机中完美拍摄的,并且它具有任何长度(无关紧要)。

我尝试了显而易见的:

Vector4d sw(point2d.x() / (0.5 * w) - 1,
point2d.y() / (0.5* h) - 1, 1, 1); // Z is now 1 instead of 0.

正如你们大多数人所预料的那样,结果是一条在屏幕中心追逐消失点的线。因此,我点击的距离中心越远,线条偏离预期方向的幅度就越大。

无论在屏幕的哪个位置,我该怎么做才能让一条线从点击的角度显示为一个点?

编辑:为了更清楚,我试图画出这样的线条:

    glBegin(GL_LINES);
line.p1 = m_proj * (m_world * m_camera) * line.p1;
line.p2 = m_proj * (m_world * m_camera) * line.p2;

glVertex3f(line.p1.x(), line.p1.y(), line.p1.z());
glVertex3f(line.p2.x(), line.p2.y(), line.p2.z());
glEnd();

最佳答案

您的初步尝试实际上非常接近。您唯一缺少的是透视鸿沟:

out[i] = point4d.block<1, 3>(0, 0) / point4d.w();

根据您的投影矩阵,您可能还需要为近平面指定 -1 的 z 值,而不是 0

是的,您的矩阵顺序 projection * model * view 看起来很奇怪。但只要您在两个过程中保持相同的顺序,您应该会得到一致的结果。

确保窗口坐标系的 y 轴指向上方。否则,您将得到反射(reflect)在水平中线的结果。

关于c++ - 从相机投影线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57965592/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com