OpenSceneGraph:尝试从鼠标屏幕坐标中提取远点和近点以进行光线投射
OpenSceneGraph: Trying to extract far and near points from mouse screen coordinates for ray casting
我正在尝试使用 OpenSceneGraph 进行光线投射。问题的上下文是我需要通过鼠标在虚拟平面上绘制线段。我不能使用 LineIntersector
因为平面不包含任何可绘制对象(我使用 osg::Plane
来表示虚拟平面)。我卡在如何提取鼠标单击坐标的远点和近点的部分(我的结果不正确)。
这是我使用的代码部分。首先计算逆变换:
osg::Matrix VPW = camera->getViewMatrix() *
camera->getProjectionMatrix() *
camera->getViewport()->computeWindowMatrix();
osg::Matrix invVPW;
invVPW.invert(VPW);
然后我根据鼠标坐标计算近点和远点; dx
和 dy
在范围内 [-1 1]
:
double dx = ea.getXnormalized();
double dy = ea.getYnormalized();
ea
是 osgGA::GUIEventAdapter &ea
类型。
然后我将获得的逆矩阵乘以鼠标坐标,将z
坐标设置为代表"far"和"near"的范围:
osg::Vec3f nearPoint = osg::Vec3f(dx, dy, 0.f) * invVPW;
osg::Vec3f farPoint = osg::Vec3f(dx, dy, 1.f) * invVPW;
结果点值似乎不正确。虽然相机明显严格地指向 y
方向 [0 1 0]
,但如果我从近到远的方向,结果向量对我来说没有多大意义,例如 [-0.310973 0.918127 -0.24564]
.
我是 OpenSceneGraph(或 OpenGL)的新手,非常感谢任何提示我做错了什么。我不确定在这里使用归一化屏幕坐标是否正确,但是,像素坐标也没有产生正确的结果。
经过一番调试,我找出了问题所在。首先,我没有正确解释远近点的结果。光线矢量的方向也不代表我期望看到的。在我将远点和近点插入实际的光线投射并与我的平面相交后,一切都变得更加清晰。
其次,我需要使用整数像素坐标,而不是标准化坐标。这是因为逆考虑了 window 矩阵。如果它对任何人都有帮助,这是我使用 OpenSceneGraph 提取远点和近点的最终代码:
osg::Matrix VPW = camera->getViewMatrix()
* camera->getProjectionMatrix()
* camera->getViewport()->computeWindowMatrix();
osg::Matrix invVPW;
bool success = invVPW.invert(VPW);
osg::Vec3f nearPoint = osg::Vec3f(ea.getX(), ea.getY(), 0.f) * invVPW;
osg::Vec3f farPoint = osg::Vec3f(ea.getX(), ea.getY(), 1.f) * invVPW;
我正在尝试使用 OpenSceneGraph 进行光线投射。问题的上下文是我需要通过鼠标在虚拟平面上绘制线段。我不能使用 LineIntersector
因为平面不包含任何可绘制对象(我使用 osg::Plane
来表示虚拟平面)。我卡在如何提取鼠标单击坐标的远点和近点的部分(我的结果不正确)。
这是我使用的代码部分。首先计算逆变换:
osg::Matrix VPW = camera->getViewMatrix() *
camera->getProjectionMatrix() *
camera->getViewport()->computeWindowMatrix();
osg::Matrix invVPW;
invVPW.invert(VPW);
然后我根据鼠标坐标计算近点和远点; dx
和 dy
在范围内 [-1 1]
:
double dx = ea.getXnormalized();
double dy = ea.getYnormalized();
ea
是 osgGA::GUIEventAdapter &ea
类型。
然后我将获得的逆矩阵乘以鼠标坐标,将z
坐标设置为代表"far"和"near"的范围:
osg::Vec3f nearPoint = osg::Vec3f(dx, dy, 0.f) * invVPW;
osg::Vec3f farPoint = osg::Vec3f(dx, dy, 1.f) * invVPW;
结果点值似乎不正确。虽然相机明显严格地指向 y
方向 [0 1 0]
,但如果我从近到远的方向,结果向量对我来说没有多大意义,例如 [-0.310973 0.918127 -0.24564]
.
我是 OpenSceneGraph(或 OpenGL)的新手,非常感谢任何提示我做错了什么。我不确定在这里使用归一化屏幕坐标是否正确,但是,像素坐标也没有产生正确的结果。
经过一番调试,我找出了问题所在。首先,我没有正确解释远近点的结果。光线矢量的方向也不代表我期望看到的。在我将远点和近点插入实际的光线投射并与我的平面相交后,一切都变得更加清晰。
其次,我需要使用整数像素坐标,而不是标准化坐标。这是因为逆考虑了 window 矩阵。如果它对任何人都有帮助,这是我使用 OpenSceneGraph 提取远点和近点的最终代码:
osg::Matrix VPW = camera->getViewMatrix()
* camera->getProjectionMatrix()
* camera->getViewport()->computeWindowMatrix();
osg::Matrix invVPW;
bool success = invVPW.invert(VPW);
osg::Vec3f nearPoint = osg::Vec3f(ea.getX(), ea.getY(), 0.f) * invVPW;
osg::Vec3f farPoint = osg::Vec3f(ea.getX(), ea.getY(), 1.f) * invVPW;