OpenGL 射线选择中射线的生成过程,代码与图示参考
2017-09-19 01:05
656 查看
Mouse Picking with Ray Casting
在射线选择中,坐标的转换原理:
http://antongerdelan.net/opengl/raycasting.html
参考:
http://blog.csdn.net/wind_hzx/article/details/40016619
构建的视图代码
所得到的示图剖面如下: (沿X轴看 向上为Y, 红线为Z轴)
黄色部分即为可见区域
在此,用 perspective 角度 3.141592f / 2.0f 为90度, 则半分开来为45度, 涉及的三角形两直线边相等,方便计算
点击屏幕只能对应一个平面二维的xy坐标,
在此以Z =1.0f为基准,即xy坐标对应视图最远处z的坐标点 (OpenGL中,XYZ最小最大值 -1 至 1)
上述代码中 perspective 对应的最远处为100,
由于相机在Z=50处,则视图最远处为Z = -50, 即可见区域最远处为竖起的黄线为Z的终点
可得下述对应点关系: (Z轴均在-50处)
若鼠标点击窗口右侧中点, 即点击OpenGL中的(0.0f, 1.0f) 点,
则发出的射线为从相机处,射至(0, 100, -50)方向 (可视区域Y轴正方向最大值为100)
若鼠标点击窗口右上角点, 即点击OpenGL中的(1.0f, 1.0f) 点,
则发出的射线为从相机处,射至(100, 100, -50)方向 (可视区域Y轴正方向最大值为100)
若鼠标点击OpenGL中的(0.0f, 0.5f) 点,
则发出的射线为从相机处,射至(0, 50, -50)方向 (可视区域Y轴正方向的一半50)
若鼠标点击OpenGL中的(0.5f, 0.5f) 点,
则发出的射线为从相机处,射至(50, 50, -50)方向 (可视区域X和Y轴正方向的一半50)
若
鼠标点击窗口中心点, 即点击OpenGL中的(0.0f, 0.0f) 点,
则发出的射线为从相机处,沿Z轴负方向走(0,0,0),即从相机往红线右侧走
上述即为点与视图间的关系
用代码进行转换:
源码下载:
http://download.csdn.net/download/yulinxx/9984821
模拟了一下,从摄像机位置点击,发射许多线至远端
在射线选择中,坐标的转换原理:
http://antongerdelan.net/opengl/raycasting.html
参考:
http://blog.csdn.net/wind_hzx/article/details/40016619
构建的视图代码
//glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 50.0f); // 相机距离原点50 //glm::vec3 cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); //glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); glm::mat4 matView = glm::lookAt(cameraPos, cameraTarg, cameraUp); glm::mat4 matProj = glm::perspective(3.141592f / 2.0f, GLfloat(WIDTH / HEIGH), 1.0f, 100.0f); // 角度, 宽高比,最近点,最远点
所得到的示图剖面如下: (沿X轴看 向上为Y, 红线为Z轴)
黄色部分即为可见区域
在此,用 perspective 角度 3.141592f / 2.0f 为90度, 则半分开来为45度, 涉及的三角形两直线边相等,方便计算
点击屏幕只能对应一个平面二维的xy坐标,
在此以Z =1.0f为基准,即xy坐标对应视图最远处z的坐标点 (OpenGL中,XYZ最小最大值 -1 至 1)
上述代码中 perspective 对应的最远处为100,
由于相机在Z=50处,则视图最远处为Z = -50, 即可见区域最远处为竖起的黄线为Z的终点
可得下述对应点关系: (Z轴均在-50处)
若鼠标点击窗口右侧中点, 即点击OpenGL中的(0.0f, 1.0f) 点,
则发出的射线为从相机处,射至(0, 100, -50)方向 (可视区域Y轴正方向最大值为100)
若鼠标点击窗口右上角点, 即点击OpenGL中的(1.0f, 1.0f) 点,
则发出的射线为从相机处,射至(100, 100, -50)方向 (可视区域Y轴正方向最大值为100)
若鼠标点击OpenGL中的(0.0f, 0.5f) 点,
则发出的射线为从相机处,射至(0, 50, -50)方向 (可视区域Y轴正方向的一半50)
若鼠标点击OpenGL中的(0.5f, 0.5f) 点,
则发出的射线为从相机处,射至(50, 50, -50)方向 (可视区域X和Y轴正方向的一半50)
若
鼠标点击窗口中心点, 即点击OpenGL中的(0.0f, 0.0f) 点,
则发出的射线为从相机处,沿Z轴负方向走(0,0,0),即从相机往红线右侧走
上述即为点与视图间的关系
用代码进行转换:
glm::mat4 matView = glm::lookAt(cameraPos, cameraTarg, cameraUp); glm::mat4 matProj = glm::perspective(3.141592f / 2.0f, GLfloat(WIDTH / HEIGH), 1.0f, 100.0f); float mouseX = 0.0f; // 鼠标点击点 float mouseY = 1.0f; // x y z w 4D裁剪坐标 Z取1,至最远处,即z离相机100,即为(0,0-50) glm::vec4 ray_clip = glm::vec4(mouseX, mouseY, 1.0f, 1.0f); glm::vec4 ray_eye = glm::inverse(matProj) * ray_clip; // 转为视觉坐标 glm::vec4 ray_world = glm::inverse(matView) * ray_eye; // 转为世界坐标 ray_world.x /= ray_world.w; ray_world.y /= ray_world.w; ray_world.z /= ray_world.w; printf("ray_world X Y Z %.3f, %.3f, %.3f\n", ray_world.x, ray_world.y, ray_world.z); glm::vec3 ray_wordXYZ = glm::vec3(ray_world); glm::vec3 ray_dir = glm::normalize(ray_wordXYZ - cameraPos); printf("ray_dir X Y Z %.3f, %.3f, %.3f\n\n", ray_dir.x, ray_dir.y, ray_dir.z);
源码下载:
http://download.csdn.net/download/yulinxx/9984821
模拟了一下,从摄像机位置点击,发射许多线至远端
相关文章推荐
- 实用的 CSS3 参考手册和代码生成工具
- 渐变代码实用的 CSS3 参考手册和代码生成工具
- OpenGL环境下的射线选择
- 自己动手实现简易代码生成器、采用文本模板文件生成服务层、服务层接口代码的做法参考
- jBPM流程执行过程图示跟踪的参考
- OpenGL-tutorials之射线求交选择(Picking with custom Ray-OBB function)
- opengl环境下的射线选择
- CSS样式生成 多张图片合成为1张 制作过程 代码控制
- sql生成(插入、修改、删除数据的存储过程)代码的存储过程
- OpenSSL 1.0.0生成p12、jks、crt等格式证书的命令个过程 -参考自http://lavasoft.blog.51cto.com/62575/1104993/
- Oracle生成单据编号存储过程的实例代码
- Visual Studio 代码生成 运行时库的选择
- 分享T4代码生成及源码(sqlite版),欢迎新手参考、修改(无版权)
- sql生成(查询数据的存储过程)代码的存储过程
- 细分球代码 (参考opengl redbook 的第二章)
- HotSpot模板解释器目标代码生成过程源码分析
- sql生成(c#调用存储过程返回数据表)代码的存储过程
- 轻量级的代码生成方案选择-Java基础-Java-编程开发
- 轻量级的代码生成方案选择
- [项目过程中所遇到的各种问题记录]学习篇——对工作以来的学习过的开源项目进行总结—动软代码生成工具