OpenGL 光线投射(拾取):考虑对象的变换 [英] OpenGL ray casting (picking): account for object's transform

查看:250
本文介绍了OpenGL 光线投射(拾取):考虑对象的变换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了拾取对象,我实现了一种类似于此处所述的光线投射算法.将鼠标单击转换为光线(具有原点和方向)后,下一个任务是将此光线与场景中的所有三角形相交,以确定每个网格的命中点.

For picking objects, I've implemented a ray casting algorithm similar to what's described here. After converting the mouse click to a ray (with origin and direction) the next task is to intersect this ray with all triangles in the scene to determine hit points for each mesh.

我还实现了基于描述的三角形相交测试算法这里.我的问题是,在执行交集时,我们应该如何考虑对象的变换?很明显,我不想把变换矩阵应用到所有的顶点然后做相交测试(太慢了).

I have also implemented the triangle intersection test algorithm based on the one described here. My question is, how should we account for the objects' transforms when performing the intersection? Obviously, I don't want to apply the transformation matrix to all vertices and then do the intersection test (too slow).


这是我正在使用的 UnProject 实现(顺便说一下,我正在使用 OpenTK).我比较了结果,它们与 GluUnProject 给我的结果相符:

private Vector3d UnProject(Vector3d screen)
{
    int[] viewport = new int[4];
    OpenTK.Graphics.OpenGL.GL.GetInteger(OpenTK.Graphics.OpenGL.GetPName.Viewport, viewport);

    Vector4d pos = new Vector4d();

    // Map x and y from window coordinates, map to range -1 to 1 
    pos.X = (screen.X - (float)viewport[0]) / (float)viewport[2] * 2.0f - 1.0f;
    pos.Y = 1 - (screen.Y - (float)viewport[1]) / (float)viewport[3] * 2.0f;
    pos.Z = screen.Z * 2.0f - 1.0f;
    pos.W = 1.0f;

    Vector4d pos2 = Vector4d.Transform(pos, Matrix4d.Invert(GetModelViewMatrix() * GetProjectionMatrix()));
    Vector3d pos_out = new Vector3d(pos2.X, pos2.Y, pos2.Z);

    return pos_out / pos2.W;
}  

然后我使用这个函数来创建一条射线(带有原点和方向):

Then I'm using this function to create a ray (with origin and direction):

private Ray ScreenPointToRay(Point mouseLocation)
{
    Vector3d near = UnProject(new Vector3d(mouseLocation.X, mouseLocation.Y, 0));
    Vector3d far = UnProject(new Vector3d(mouseLocation.X, mouseLocation.Y, 1));

    Vector3d origin = near;
    Vector3d direction = (far - near).Normalized();
    return new Ray(origin, direction);
} 

推荐答案

您可以改为将每个对象的逆变换应用于光线.

You can apply the reverse transformation of each object to the ray instead.

这篇关于OpenGL 光线投射(拾取):考虑对象的变换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆