1. Three.js中的拾取
1.1. 从模型转到屏幕上的过程说开
由于图形显示的基本单位是三角形,那就先从一个三角形从世界坐标转到屏幕坐标说起,例如三角形abc
乘以模型视图矩阵就进入了视点坐标系,其实就是相机所在的坐标系,如下图:
进入视点坐标系后,再乘以投影矩阵,就会变换到一个立方体内,如下图:
这个时候整个三角形就位于中心位于坐标系原点,边长为2的立方体内,在这个立方体内,三角形要计算光照,要裁剪,然后乘以视口矩阵,最后转到屏幕上。
转到屏幕上后,三角形的所有点的Z坐标就是深度坐标,一定在(0, 1)这个区间内,那么哪些点的Z坐标是0呢,在投影坐标系中,一定是投影视景体的前剪切平面上的点,而投影视景体的后剪切平面上的点的Z坐标就是1。
1.2. 思路来了
根据以上三角形转换到屏幕坐标上的过程可以分析出,鼠标在屏幕上点击的时候,可以得到二维坐标p(x, y),再加上深度坐标的范围(0, 1), 就可以形成两个三位坐标A(x, y, 0), B(x, y, 1), 由于它们的Z轴坐标是0和1,则转变到投影坐标系的话,一定分别是前剪切平面上的点和后剪切平面上的点,也就是说,在投影坐标系中,A点一定在能看见的所有模型的最前面,B点一定在能看见的所有的模型的最后边,假设视口矩阵的逆矩帧,投影矩阵的逆矩阵,模型视图矩阵的逆矩阵为M, N, P,则 P * N * M * A = A1, P * N * M * B = B1, 在世界坐标系中,点A1B1就可以形成一个射线,此射线和模型再求交,就能选中模型。如下图是在视点坐标系中的情形。注意,求交可以在视点坐标系或者世界坐标系计算都可以,但一般会在世界坐标坐标系中计算。
1.3. 拾取的优化,射线和AABB包围盒求交
如果射线和所有的模型求交,显然不是一个好办法,一般情况下会进行一些优化,比如先和模型的包围盒求交,如果和模型的包围盒不相交的话,就放过去,否则就接着往下进行,和模型的所有三角面片求交。
那么什么是包围盒呢?在计算机图形学与计算几何领域,一组物体的包围体就是将物体组合完全包容起来的一个封闭空间。将复杂物体封装在简单的包围体中,就可以提高几何运算的效率。通常简单的物体比较容易检查相互之间的重叠。其中有一种包围盒叫做AABB, AABB的全称是axis aligned bounding box,就是我们常常提到轴向包围盒,这个盒子的边是平行于x/y/z轴的。 所有的2d和3d物体都是由点组成的,所以只要找出这些物体的最大值点和最小值点,那么就可以使用这两个点表示该物体的AABB包围盒了。
检测碰撞的时候我们只需要检测这些物体的AABB(即他们的最大值点和最小值点)是否相交,就可以判断是否碰撞了。
1.4. 射线和三角形相交
判断射线和包围盒是否求交后,就轮到判断是否和三角形求交了,最先想到的是 首先判断射线是否与三角形所在的平面相交,如果相交,再判断交点是否在三角形内。判断射线是否与平面相交, 判断点是否在三角形内.
1.5. THREE.JS中求交的代码实现
three.js中的一个案例,名字叫webgl_interactive_lines.html,可以选中一根线,并显示一个小球。根据以上的思路,代码注释如下:
//鼠标点击的屏幕坐标转换到视点坐标系
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 ).unproject( camera );
//在视点坐标系中形成射线
raycaster.set( camera.position,vector.sub( camera.position ).normalize() );
//射线和模型求交,选中一系列直线
var intersects = raycaster.intersectObjects( parentTransform.children, true);
if ( intersects.length > 0 ) {
if ( currentIntersected !== undefined )
{
currentIntersected.material.linewidth = 1;
}
//第一个直线
currentIntersected = intersects[ 0 ].object;
currentIntersected.material.linewidth = 5;
//把球设为可见,并且位置移到鼠标点击的屏幕位置
sphereInter.visible = true;
sphereInter.position.copy( intersects[ 0 ].point );
}
交流图形学的一切,尤其是大型程序的设计,每天有原创文章
微信公众号: GraphicsPlatform
qq群: 559684273
qq: 1829634717
拾取模型的原理及其在THREE.JS中的代码实现的更多相关文章
-
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...
-
【JavaScript】JS中没有代码块的概念
<script> var m = "roboce"; if(m === "roboce"){ var k = "haha"; } ...
-
js中深拷贝代码实现
function copy(original,o){ if(typeof original != 'object') return original; var o = o || (Array.isAr ...
-
WebGL射线拾取模型——八叉树优化
经过前面2篇WebGL射线拾取模型的文章,相信大家对射线和模型面片相交的原理已经有所了解,那么今天我们再深入探究关于射线拾取的一个问题,那就是遍历场景中的所有与射线相交的模型的优化问题.首先我们来复习 ...
-
在 Node.js 中引入模块:你所需要知道的一切都在这里
本文作者:Jacob Beltran 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58eaf471a58c240ae35bb ...
-
JS中window.document对象
小知识点注:外面双引号,里面的双引号改为单引号: 在div里面行高设置和整个外面高度一样,才能用竖直居中,居中是行居中 文本框取出来 ...
-
js中匿名函数
今天碰到一道题,里面既包含了匿名函数的知识,也包含了预编译,函数的传参(形参),感觉迷迷糊糊的,所以想着做个总结. var foo={n:1}; (function(foo){ console.log ...
-
JS中同步显示并分割输入的数字字符串
题目比较晦涩,来张图来说明要表达的效果: 第一张图的效果就是,用户输入一个数字,上面就显示一个大层,然后显示输入的数字,并把数字用空格按照每四位分割出来.好像在建行的网上银行上面就有这种效果.第二个图 ...
-
JS基础_代码块
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
随机推荐
-
jdk 环境变量配置
环境变量:Path %JAVA_HOME%\bin;%JAVA_HOME%\jre\binCLASSPATH .;%JAVA_HOME%\lib;JAVA_HOME D:\java\jdk1.5.0_ ...
-
struts 异常机制
1.try-catch 在Action中通过try-catch捕获异常,在catch中返回字符串, 通过返回的字符串在Action的result元素中进行匹配,最终返回响应的页面 2. 局部异常映射 ...
-
.NET使用Com组件的一点点教训笔记~
中控IFACE系列的产品,二次开发包 zkemkeeper.dll 在system32 ,SySWoW64都注册了,就是他妈的用不了. 最后,在 system32 ,SySWoW64 注册了,然后把需 ...
-
Fortran向C传递NULL值
在很多C或C++的头文件定义中,NULL被指定定义为0,这里不再具体展开 gfortran的手册关于iso c binding的章节,定义NULL如下 Moreover, the following ...
-
Struts2返回JSON对象的方法总结
如果是作为客户端的HTTP+JSON接口工程,没有JSP等view视图的情况下,使用Jersery框架开发绝对是第一选择.而在基于Spring3 MVC的架构下,对HTTP+JSON的返回类型也有很好 ...
-
选择问题(选出第i个最小元素)
通过分治法解决的分析(还有其他方法解决选择问题如使用 堆) 1 同快速排序一样,对输入的数组进行递归分解 不同的是:快速排序会递归处理分解的两边,而选择问题只处理需要的一边 2 选择问题的期望时间代价 ...
-
严重: The web application [] registered the JDBC driver 错误
近日发现启动tomcat的时候报如下警告: -- :: org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc 严重: The ...
-
go语言的安装和配置,以及包引用
1.下载和安装 首先大家可以去官网下载 http://golang.org/dl/ 如果官网你看不懂的话,可以到这里下载: http://golangtc.com/download ,这里也提供了百度 ...
-
Objective-C探究alloc方法的实现
OS X,iOS中的大部分作为开源软件公开在 Apple Open Source 上.虽然想让大家参考NSObject类的源代码,但是很遗憾,包含NSObject类的Foundation框架没有公开. ...
-
hihocoder 1015题
代码 #include <iostream> #include <string> #include <typeinfo> #include <vector&g ...