- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 glm::unproject() 将我的 SDL 鼠标坐标转换为 x/z 平面上的世界位置 vector 。基本上我想弄清楚用户用鼠标点击了哪个“x/z”坐标。
来自 other stack overflow answers我想到需要调用 glm::unproject()。我认为我向它传递了错误的参数,因为我为世界位置返回的值(打印的 std std::cerr)不是我期望的世界位置值。
我是否在下面正确构造了 glm::unproject() 的参数?具体来说,我应该结合相机的世界位置和 View 矩阵(使用 glm::lookAt 计算)来计算传递给 glm::unproject 的模型 View 矩阵吗?
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;
}
在下图中,我有以下设置。
相机注视目标 = (0, 0, 0)
相机世界位置 = (-0.009, 5.107, -0.368)
(mouse_x, mouse_y, mouse_z) = (286, 393, 0)
如果您查看下图,您会发现我的鼠标悬停在世界位置 (3, 0, 0) 上,如网格所示。我希望计算鼠标的世界位置(如图所示)会返回 vector (3, 0, 0)。它没有,而是我得到了 vector :(0.049, 5.007, -0.360)。
有没有人看到我可能哪里出错了?我假设我在某处做出了某种不正确的假设。
最佳答案
您的假设是错误的: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) 上计算一个点,因为近平面距离通常非常小,可能会导致数值问题。
结论:提供的所有值都是正确的,但您只是没有计算出预期的值。
关于c++ - 正确调用 glm::unproject() ,感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48125247/
我正在尝试学习Rust。我正在阅读一本书online,该书实现了unix程序cat。现在,我试图读取作为像cargo run file1.txt file2.txt这样的参数传递的文件的内容,但是程序
我在 GHC 8.0.1 中遇到了一个带有种类索引 (?) GADT 的奇怪情况,其中在类型与种类签名中引入 foralls 会产生不同的类型检查行为。 考虑以下数据类型: {-# LANGUAGE
我正在使用 Perl 5.10 开发应用程序,HTML::Mason和 Apache 2.2。这是我第一次在大型项目中使用 Perl 5.10。我每隔一段时间就会出现奇怪的行为。应用程序因一个非常奇怪
我正在尝试将文件上传到aws中的rust中,因为我使用的是 rusoto_s3 的s3 rust客户端,当这些部分从单个线程发送时,我设法使分段上传代码正常工作不是我想要的,我想上传大文件,并且希望能
我是一名优秀的程序员,十分优秀!