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 );

}

欢迎加微信 nuonuodi_1, 交流更多的技术问题

转载于:https://www.cnblogs.com/lizhengjin/p/5914216.html

拾取模型的原理及其在THREE.JS中的代码实现相关推荐

  1. 分析洋葱模型实现原理,在自己项目中接入洋葱模型

    分析洋葱模型实现原理,在自己项目中接入洋葱模型 上一篇文章初识洋葱模型,分析中间件执行过程,浅析koa中间件源码简单的介绍了 基于 koa 的洋葱模型的中间件的运行过程,了解了一下中间件的写法 不过基 ...

  2. three相机在模型上_深入理解Three.js中透视投影照相机PerspectiveCamera

    前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...

  3. js 中 java 代码_在js中嵌套java代码

    jsp中有时候在js中操作某些java后台传递过来的数据逻辑比较复杂,比如list内容的遍历,可以直接在页面上添加java脚本来执行内容,代码如下: //在js中插入java代码操作 //取出java ...

  4. 深入解析js中的函数

    写在前面 由于词语匮乏,本文继续沿用"深入解析xxx"这个俗套的命名,但是是真的很深入(你要信我啊).如果本文对你有用,欢迎收藏,如果喜欢我的文章,欢迎点赞和关注专栏. 函数可以说 ...

  5. JS中window.document对象

    小知识点注:外面双引号,里面的双引号改为单引号:                  在div里面行高设置和整个外面高度一样,才能用竖直居中,居中是行居中                  文本框取出来 ...

  6. JS学习笔记 - 代码复用

    本文章记录本人在学习 JavaScript 中看书理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习. js 中复用代码 说道代码复用,一般都会涉及到对象继承.在js中有许多可以选择的继承方 ...

  7. 关于JS中一些重要的api实现,巩固你的原生JS功底

    自 Node.js 面世以来,它获得了大量的赞美和批判.这种争论会一直持续,短时间内都不会结束.而在这些争论中,我们常常会忽略掉所有语言和平台都是基于一些核心问题来批判的,就是我们怎么去使用这些平台. ...

  8. js中导入引用外部js

    方法一 使用绝对路径,稳妥引入js.适用于各种浏览器. 在js中加入代码: var baseurl = window.location.protocol+'//'+window.location.ho ...

  9. bootstrapTable printThis打印插件 中 printThis.js中的一个buge

    printThis打印插件还有一个大坑,先看看,一定要注意: 如果你用的开发工具(HBuilder.exe)访问形式是ip的形式如:http://127.0.0.1:8020/TestBootStra ...

最新文章

  1. GitLab 8.7发布
  2. oracle imp 工具可能出现的问题
  3. 数学建模 概率空间与统计结构
  4. dubbo协议原理机制 单一长连接
  5. TYAN_S8230做硬Raid
  6. ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR
  7. node工程默认url_node命令行工具之实现项目工程自动初始化的标准流程
  8. 强烈推荐!FlyAI机器学习数据竞赛启动,丰厚奖金等你来拿
  9. 用PHP控制您的浏览器cache
  10. 微信iOS 7.0.5版本终于上线:新功能好方便!
  11. c 复杂的前置后置面试题_练一练!3道经典嵌入式C 面试题,答案在文末
  12. 最常用的springmvc注解使用技巧
  13. 电赛练习之旋转倒立摆
  14. ic卡c语言程序,sle4442程序(ic卡程序,C语 - 控制/MCU - 电子发烧友网
  15. mysql端口被占用了如何解决_如何解决Win10安装MYSQL端口被占用?
  16. 手机开机启动慢是什么原因_手机开机的速度太慢怎么办
  17. Android USB tethering相关代码
  18. 小知识·Git、Github、Gitlab以及Gitee的关系
  19. 交换机基础知识和VLAN概述
  20. win10c语言弹出框,win10系统启动程序时弹出异常代码c0000005的解决技巧

热门文章

  1. python小白逆袭大神课程心得_python小白逆袭大神(深度学习7日训练营)——心得体会...
  2. composer在windows中安装失败
  3. codeblocks怎么用已封装的类_mitoq 在新西兰用着怎么样?已入手mitoq,我的感受
  4. excel表格怎么调整行高和列宽_8个实用Excel小技巧,谁用谁说好
  5. 『数据库』震惊,某博主为吸引眼球拿出压箱底SQL总结,如果你没看那就吃亏了!(超级详细的SQL基础,你还不会的话就别学数据库了)
  6. 洛谷2014 选课(树形DP)树形背包问题
  7. 【个人网盘-updog】使用updog建立个人网盘,so easy
  8. gcc 4.4.2 安装
  9. Python矩阵的用法(使用numpy)
  10. 利用PyCaret的力量