所以基本上我已经使用OpenGL制作了一个可以执行3D光线拾取的程序。如果Camera View Direction Ray
接触/相交任何东西(不是空气),然后在交点/点处会呈现一个紫色的小盒子。
如果光线与任何“红色框”相交,与光线相交的一次将变为绿色。地面和墙壁根本不会改变颜色或纹理。
例子:
我目前进行 3D 光线拾取的方法是获取相机的 View 方向光线,然后仅计算交点。我用于计算交点的函数不会作为 bool 值返回,而是作为 3D 向量(交点本身的坐标)返回
问题
所以我想要实现的是计算采摘射线,但是根据鼠标当它是不是 锁定在屏幕上。
示例 - 所以在这里你可以看到紫色框位于十字准线处,但如果我要解锁鼠标并移动它(在屏幕顶部,像往常一样)并将其移动到绿色 X 标记的中心我已经绘制,然后我想计算从相机中心到屏幕顶部鼠标坐标的光线。
当前的测试和想法
这应该只是一个数学问题。这只是我目前用来计算光线(并尝试计算第二条光线)的简短列表
鼠标 X 和 Y 原点 (0x0) 位于窗口/框架的左下角。
计算主采摘射线本身
Vector3D position = new Vector3D(
camera.x,
camera.y,
camera.z);
Vector3D direction = new Vector3D(
Math.cos(Math.toRadians(camera.pitch)) * -Math.sin(Math.toRadians(-camera.yaw)) * camera.far,
Math.cos(Math.toRadians(camera.pitch)) * cameara.far,
Math.cos(Math.toRadians(camera.pitch)) * -Math.sin(Math.toRadians(-camera.yaw)) * camera.far);
direction.normalize();
Ray3D ray = new Ray(position, direction);
这就是我如何计算主拾取射线本身(锁定鼠标的拾取射线)。我自己制作了类(class),尽管它们应该有意义(
Vector3D
、 Ray3D
等)和 normalize()
方法完全按照它所说的去做,将向量归一化。主意
因此,当我尝试使用鼠标坐标进行计算时,我在调用
direction.normalize();
之前插入了以下代码,所以在创建 Vector3D direction
之后.if (!Mouse.isGrabbed())
{
float mx = Mouse.getX() / (float) scene.width - 0.5f;
float my = Mouse.getY() / (float) scene.height - 0.5f;
mx *= camera.far;
my *= camera.far;
line.b.x += mx;
line.b.y += my;
line.b.z += mz;
}
当鼠标没有被锁定/抓取时,这给了我一个奇怪的结果。这是有道理的,因为我只是在胡思乱想并尝试一些首先出现在我脑海中的事情。
我猜我需要根据俯仰、偏航和滚转来转换鼠标坐标。虽然我不知道,我将如何去做。
所以我希望有人可以帮助我实现这一目标和/或给我一些资源,这样我就可以了解如何做我想做的事情。
额外的
如果您需要更多关于此的信息,请写评论,我会尽力而为。
答案 - 感谢 fen
我最终使用了 fen现在的方式,因为它比必须计算所有内容简单得多!
FloatBuffer projection = BufferTools.createFloatBuffer(16);
FloatBuffer modelview = BufferTools.createFloatBuffer(16);
IntBuffer viewport = BufferTools.createIntBuffer(16);
glGetFloat(GL_PROJECTION_MATRIX, projection);
glGetFloat(GL_MODELVIEW_MATRIX, modelview);
glGetInteger(GL_VIEWPORT, viewport);
float win_x = Mouse.getX();
float win_y = Mouse.getY();
FloatBuffer position_near = BufferTools.createFloatBuffer(3);
FloatBuffer position_far = BufferTools.createFloatBuffer(3);
gluUnProject(win_x, win_y, 0f, modelview, projection, viewport, position_near);
gluUnProject(win_x, win_y, 1f, modelview, projection, viewport, position_far);
Ray3D ray = new Ray3D(
new Vector3D(
position_near.get(0),
position_near.get(1),
position_near.get(2)),
new Vector3D(
position_far.get(0),
position_far.get(1),
position_far.get(2)));
最佳答案
这是我创建鼠标射线的代码:
double matModelView[16], matProjection[16];
int viewport[4];
// get matrix and viewport:
glGetDoublev( GL_MODELVIEW_MATRIX, matModelView );
glGetDoublev( GL_PROJECTION_MATRIX, matProjection );
glGetIntegerv( GL_VIEWPORT, viewport );
// window pos of mouse, Y is inverted on Windows
double winX = (double)mouseX;
double winY = viewport[3] - (double)mouseY;
// get point on the 'near' plane (third param is set to 0.0)
gluUnProject(winX, winY, 0.0, matModelView, matProjection,
viewport, m_start.x, &m_start.y, &m_start.z);
// get point on the 'far' plane (third param is set to 1.0)
gluUnProject(winX, winY, 1.0, matModelView, matProjection,
viewport, m_end.x, &m_end.y, &m_end.z);
// now you can create a ray from m_start to m_end
OpenGL 2.0,但希望你能明白。
部分链接 :Select + Mouse + OpenGL
关于opengl - 3D 光线拾取在鼠标未锁定时使用鼠标坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18244678/