问题描述
所以基本上我做了使用OpenGL,可以执行3D雷采摘的程序。如果摄像机视图方向光线
触及/相交任何东西(这是不是空气),那么一点点紫色框将获得在交叉点/分呈现。
如果射线相交任何相交的射线会变成绿色的红箱的一次。在所有的地面和墙壁也不会改变颜色或纹理。
例如:
如果图片太小,可以看到所有的细节,然后点击此处看到它在高的分辨率。
目前的方式,我做3D雷采摘,是获得相机的视图方向光线,然后只计算了十字路口。 我的函数计算交叉口不会返回一个布尔值,它返回一个三维矢量的
(路口自身的坐标)问题
所以,我想要实现的是计算出的采摘雷的,而是根据当它是鼠标的不可以锁定屏幕。
示例 - 所以在这里你可以看到紫色的盒子是在十字线,但如果我要解锁鼠标移动(在屏幕的上方,像正常)和其移动绿色X标记我有平局的中心,那么我要计算从摄像机中心到鼠标的光线在屏幕上坐标。
电流试验和思路
这应该只是一个数学问题。这里的事情就短名单我目前使用来计算雷(并试图计算第二线)
- Cameara X,Y,Z
- 在摄像头俯仰偏航卷(卷没有使用现在)
- 相机近远(距离)
- 相机的Fov
- 相机看点
- 鼠标X,Y(在屏幕本身的顶部)
- Sceen宽度,高度
的鼠标X'放大器; Y原点(为0x0)是在窗口/框的左下角。的
计算主要的采摘雷的本身
的Vector3D位置=新的Vector3D(
camera.x,
camera.y,
camera.z);
的Vector3D方向=新的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线=新雷(位置,方向);
这就是我是如何计算的主要采摘射线本身(采摘光线的锁定鼠标)。我做了类自己,但他们应该感(的Vector3D
, Ray3D
等)和正常化()
方法不正是它说,标准化的载体。
创意
所以,当我试图计算使用鼠标坐标我插入下面的code权之前,我打电话 direction.normalize();
,经过这么右创建的Vector3D方向
。
如果(!Mouse.isGrabbed())
{
浮MX = Mouse.getX()/(浮点)scene.width - 0.5F;
浮动我= Mouse.getY()/(浮点)scene.height - 0.5F;
MX * = camera.far;
我* = camera.far;
line.b.x + = MX;
line.b.y + =我;
line.b.z + = MZ;
}
这给了我一个奇怪的结果,当鼠标未锁定/抓起。这是有道理的,因为我只是插科打诨和尝试一些发自首先在脑海里的东西。
我猜我需要翻译根据俯仰,偏航和滚动鼠标的坐标。虽然我没有任何想法,我怎么会去这样做。
所以,我希望有别人可以帮助我实现这一目标和/或给我某种资源,所以我能理解怎么做我想要做的事情。
附加
如果您需要了解更多的相关信息,只写一个评论,我会尽我所能。
答案 - 感谢分
我结束了使用芬的方式,现在,因为它不必计算一切简单多了!
FloatBuffer投影= BufferTools.createFloatBuffer(16);
FloatBuffer模型观察= BufferTools.createFloatBuffer(16);
IntBuffer视= BufferTools.createIntBuffer(16);
glGetFloat(GL_PROJECTION_MATRIX,投影);
glGetFloat(GL_MODELVIEW_MATRIX,模型观察);
glGetInteger(GL_VIEWPORT,视口);
浮win_x = Mouse.getX();
浮win_y = Mouse.getY();
FloatBuffer position_near = BufferTools.createFloatBuffer(3);
FloatBuffer position_far = BufferTools.createFloatBuffer(3);
gluUnProject(win_x,win_y,0F,模型观察,投影,视口,position_near);
gluUnProject(win_x,win_y,1F,模型观察,投影,视口,position_far);
Ray3D线=新Ray3D(
新的Vector3D(
position_near.get(0),
position_near.get(1),
position_near.get(2)),
新的Vector3D(
position_far.get(0),
position_far.get(1),
position_far.get(2)));
这是我的$ C $下创建的鼠标线:
双matModelView [16],matProjection [16];
视口INT [4];
//获取矩阵和视口:
glGetDoublev(GL_MODELVIEW_MATRIX,matModelView);
glGetDoublev(GL_PROJECTION_MATRIX,matProjection);
glGetIntegerv(GL_VIEWPORT,视口);
//窗口的鼠标POS机,Y是倒在Windows
双WINX =(双)mouseX;
双威锐=视[3] - (双)mouseY的;
//获取点上的近平面(第三个参数设置为0.0)
gluUnProject(WINX,酒味,0.0,matModelView,matProjection,
视口,m_start.x,和放大器; m_start.y,和放大器; m_start.z);
//取得点上的远平面(第三参数被设定为1.0)
gluUnProject(WINX,酒味,1.0,matModelView,matProjection,
视口,m_end.x,和放大器; m_end.y,和放大器; m_end.z);
//现在你可以创建M_START一个射线m_end
的OpenGL 2.0,但希望你的想法。
有些链接:选择+鼠标+的OpenGL
So basically I've made a program using OpenGL which can perform 3D Ray Picking. If the Camera View Direction Ray
touches/intersects anything (which isn't air) then a little purple box will get rendered at the intersection point/points.
If the ray intersects with any of the "Red Boxes" the once that are intersecting with the ray will turn green. The ground and walls won't change color or texture at all.
Examples:
If the image is too small to be able to see all the details then click here to see it in a high resolution.
The current way I do the 3D Ray Picking, is getting the camera's view direction ray, and then just calculating for intersections. My function for calculating intersections doesn't return as a boolean, it returns as a 3D Vector (the coordinates of the intersection itself)
The Question
So what I'm trying to achieve is to calculate the Picking Ray, but according to the mouse when it's not locked to the screen.
Example - So here you can see the purple box is at the crosshair, though if I were to unlocked the mouse and move it (on top of the screen, like normally) and move it over to the center of the green X mark I've draw, then I want to calculate the ray from the camera center to the mouse coordinate on top of the screen.
Current Tests and Ideas
This should just be a mathematical problem. Here is just a short list of the things I currently use to calculate the Ray (and trying to calculate the second ray)
- Cameara X, Y, Z
- Camera Pitch Yaw Roll (Roll not used right now)
- Camera Near Far (distances)
- Camera Fov
- Camera Aspect
- Mouse X, Y (On top of the screen itself)
- Sceen Width, Height
The Mouse X & Y origin (0x0) is in the bottom left corner of the window/frame.
Calculating the main Picking Ray itself
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);
That is how I calculate the main picking ray itself (the picking ray for the locked mouse). I made the classes myself, though they should make sense (Vector3D
, Ray3D
, etc) and the normalize()
methods does exactly what it says, normalizes the vector.
Idea
So when I tried to calculate using the mouse coordinates I inserted the following code right before I'm calling direction.normalize();
, so right after creating the 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;
}
That gives me a weird result, when the mouse isn't locked/grabbed. It makes sense since I was just messing around and trying some of the things that came first in my mind.
I'm guessing that I need to translate the mouse coordinates according to the pitch, yaw and roll. Though I don't have any idea, how I would go about doing that.
So I'm hoping that there is somebody that can help me achieving this and/or give me some sort of resource so I can understand how to do what I'm trying to do.
Extra
If you need more info about this, just write a comment and I will do my best.
Answer - Thanks to fen
I ended up using fen's way for now, since it was a lot simpler than having to calculate everything!
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)));
here is my code for creating a mouse ray:
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, but hope you get the idea.
Some links: Select + Mouse + OpenGL
这篇关于3D雷采摘使用鼠标坐标,当鼠标没有被锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!