Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 正确调用glm::unproject(),有点困惑_C++_Opengl_Matrix_Glm Math - Fatal编程技术网

C++ 正确调用glm::unproject(),有点困惑

C++ 正确调用glm::unproject(),有点困惑,c++,opengl,matrix,glm-math,C++,Opengl,Matrix,Glm Math,我试图使用glm::unject()将SDL鼠标坐标转换为x/z平面上的世界位置向量。基本上,我想找出用户用鼠标点击的“x/z”坐标 从那时起,我需要调用glm::unproject()。我想我传递的参数是错误的,因为我为世界位置(打印的std::cerr)返回的值不是我所期望的世界位置值 我是否正确地构造了下面glm::unproject()的参数?具体来说,我应该结合相机的世界位置和视图矩阵(使用glm::lookAt计算)来计算传递到glm::unproject中的modelview矩阵吗

我试图使用glm::unject()将SDL鼠标坐标转换为x/z平面上的世界位置向量。基本上,我想找出用户用鼠标点击的“x/z”坐标

从那时起,我需要调用glm::unproject()。我想我传递的参数是错误的,因为我为世界位置(打印的std::cerr)返回的值不是我所期望的世界位置值

我是否正确地构造了下面glm::unproject()的参数?具体来说,我应该结合相机的世界位置和视图矩阵(使用glm::lookAt计算)来计算传递到glm::unproject中的modelview矩阵吗

struct Dimensions {
  int x, y, w, h;
};

glm::mat4
Camera::view_matrix() const
{
  // VIEW matrix is created by looking at some target member
  auto const& target = target_->translation;
  auto const position_xyz = world_position();

  glm::vec3 const UP{0, 1, 0};
  return glm::lookAt(position_xyz, target, UP);
}

glm::mat4
Camera::projection_matrix() const
{
  auto const fov = glm::radians(90.0f);
  return glm::perspective(fov, 4.0f/3.0f, 0.1f, 200.0f);
}

glm::vec3
calculate_worldpos(Camera const& camera, int const mouse_x, int const mouse_y)
{
  float const width = 1024.0f, height = 768.0f;
  glm::vec4 const viewport = glm::vec4(0.0f, 0.0f, width, height);
  glm::mat4 const modelview = camera.view_matrix();
  glm::mat4 const projection = camera.projection_matrix();

  float z = 0.0;
  glm::vec3 screenPos = glm::vec3(mouse_x, height - mouse_y - 1, z);
  std::cerr << "screenpos: xyz: '" << glm::to_string(screenPos) << "'\n";

  glm::vec3 worldPos = glm::unProject(screenPos, modelview, projection, viewport);
  std::cerr << "worldpos: xyz: '" << glm::to_string(worldPos) << "'\n";
  return worldPos;
}
struct维度{
int x,y,w,h;
};
glm::mat4
摄像机::视图矩阵()常数
{
//视图矩阵是通过查看某个目标成员创建的
自动常量&target=target->translation;
auto const position_xyz=世界位置();
glm::vec3 const UP{0,1,0};
返回glm::注视(位置xyz,目标,向上);
}
glm::mat4
摄影机::投影矩阵()常数
{
自动常数fov=glm::弧度(90.0f);
返回glm::透视图(视野,4.0f/3.0f,0.1f,200.0f);
}
glm::vec3
计算世界位置(相机常数和相机,鼠标常数x,鼠标常数y)
{
浮动常数宽度=1024.0f,高度=768.0f;
glm::vec4常量视口=glm::vec4(0.0f,0.0f,宽度,高度);
glm::mat4 const modelview=camera.view_matrix();
glm::mat4 const projection=camera.projection_matrix();
浮动z=0.0;
glm::vec3屏幕位置=glm::vec3(鼠标x,高度-鼠标y-1,z);

std::cerr您的假设是错误的:glm::unproject返回输入的世界空间坐标,该坐标由像素坐标中的xy位置和存储深度值的z坐标给出。在屏幕上的每个像素上,世界空间中有无限多个点投影到此像素(所有这些都取决于从投影中心穿过该像素的光线)。通过选择深度坐标来确定所需的深度坐标,该深度坐标将导致该光线上的一个特定点。选择z=0意味着结果将始终是相机近平面上的一个点

您实际查找的是该光线(穿过摄影机位置和计算点)与xz平面(其中y=0)的交点

光线由其上的两点(相机位置C,靠近平面点p)给出,如下所示:

                  -0.009            0.058
C + l * (P-C) = (  5.107 ) + l * ( -0.100 )
                  -0.368            0.008
,其中l是自由变量

如前所述,我们正在寻找y=0平面的交点(a,b),因此我们可以建立以下方程:

  -0.009            0.058       a
(  5.107 ) + l * ( -0.100 ) = ( 0 )
  -0.368            0.008       b
求解l的y方程(
5.107+l*-0.1=0
)会导致
l=51.07
。将x和z的方程粘贴回:

a = -0.009 + 51.07 * 0.058 = 2.95306
b = -0.368 + 51.07 * 0.008 = 0.04056
这接近于预期的世界空间位置。差异很可能是因为您在问题中显示了四舍五入的数字。出于准确性原因,我也不会计算近平面上的点,而是远平面上的点(z=1)因为近平面距离通常很小,可能导致数值问题


结论:提供的所有值都是正确的,但您只是没有计算预期值。

您的假设是错误的:glm::unproject返回输入的世界空间坐标,该坐标由像素坐标中的xy位置和存储深度值的z坐标给出。屏幕上的每个像素上都有一个infinite世界空间中投影到此像素的点的数量(从投影中心穿过此像素的光线上的所有点)。通过选择深度坐标来确定所需的深度坐标,该坐标将导致此光线上的一个特定点。选择z=0表示结果将始终是相机近平面上的一个点

您实际查找的是该光线(穿过摄影机位置和计算点)与xz平面(其中y=0)的交点

光线由其上的两点(相机位置C,靠近平面点p)给出,如下所示:

                  -0.009            0.058
C + l * (P-C) = (  5.107 ) + l * ( -0.100 )
                  -0.368            0.008
,其中l是自由变量

如前所述,我们正在寻找y=0平面的交点(a,b),因此我们可以建立以下方程:

  -0.009            0.058       a
(  5.107 ) + l * ( -0.100 ) = ( 0 )
  -0.368            0.008       b
求解l的y方程(
5.107+l*-0.1=0
)会导致
l=51.07
。将x和z的方程粘贴回:

a = -0.009 + 51.07 * 0.058 = 2.95306
b = -0.368 + 51.07 * 0.008 = 0.04056
这接近于预期的世界空间位置。差异很可能是因为您在问题中显示了四舍五入的数字。出于准确性原因,我也不会计算近平面上的点,而是远平面上的点(z=1)因为近平面距离通常很小,可能导致数值问题


结论:提供的所有值都是正确的,但您只是没有计算出预期值。

为什么要通过相机的世界坐标再次转换modelview矩阵?lookAt矩阵不是已经这样做了吗?请添加所有输入值(相机参数、鼠标坐标、视口大小等),您当前的结果以及您的期望值。感谢您的反馈,我已经完成了计算,并显示了我期望返回的值,以及我实际从计算中获得的值。我还添加了一个图像,显示了我正在尝试执行的操作。另外,在额外的翻译中留下错误,您是正确的glm::lookAt()确实可以处理转换。为什么要按摄影机的世界坐标再次转换modelview矩阵?lookAt矩阵是否已经完成了转换?请添加所有输入值(摄影机参数、鼠标坐标、视口大小等),您当前的结果和您的期望值。感谢您的反馈,我已经完成了计算,并显示了我期望返回的值,以及我实际从计算中获得的值。我还添加了一个图像,显示了我正在尝试返回的值