three.js raycaster射线碰撞的坑 (当canvas大小 不是屏幕大小是解决拾取物体的办法)
这里只是记录一下坑,方便查阅,内容主要援引自:three.js Raycaster 射线拾取 canvas不占满整屏时射线拾取存在偏差
1. 世界坐标系: 世界坐标系位于屏幕的中心(0,0,0),往右侧是x轴,往上是y轴,垂直屏幕朝向的是z轴.所以屏幕的左下角是(-1,-1),右上角是(1,1);
2. 屏幕坐标系: webgl会将三维的坐标经过计算,在屏幕里正常显示.
在根据模型或者网格去进行碰撞测试时,我们选择的点一般就是摄像机的位置(相当于人眼的位置,在屏幕上点击的位置,组成一条射线)
初始化,比如:
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse,camera) // 也可以给构造函数传参的形式写
var intersects = raycaster.intersectObjects( scene.children ); // 这里的children,如果你是引入的模型,那么模型加载parse的时候,可以使用一个变量存储你需要检测的对象,这里必须传入
但是当你的浏览器屏幕的缩放比不一致的时候,你就会看到一个很奇葩的现象,你的模型偏了,你的鼠标永远都选不到目标,然后审查一下元素,可能会出现winner.innerHeight,window.innerWidth 远大于或者小于屏幕视口实际尺寸的情况(我当时还以为是无限鼠标的锅,后来才想到可能是屏幕的缩放导致的).这时需要重新去定义射线的初始化.我在开始部分原因的那段代码就可以很好的解决:
functioninitRay(){
// 屏幕坐标转标准设备坐标
let x = ((event.clientX - mainCanvas.getBoundingClientRect().left) / mainCanvas.offsetWidth) *2-1;// 标准设备横坐标
// 这里的mainCanvas是个dom元素,getBoundingClientRectangle会返回当前元素的视口大小.
let y = -((event.clientY - mainCanvas.getBoundingClientRect().top) / mainCanvas.offsetHeight) *2+1;// 标准设备纵坐标
let standardVector =newTHREE.Vector3(x, y,1);// 标准设备坐标
// 标准设备坐标转世界坐标
let worldVector = standardVector.unproject(camera);
// 射线投射方向单位向量(worldVector坐标减相机位置坐标)
let ray = worldVector.sub(camera.position).normalize();
// 创建射线投射器对象
letrayCaster =newTHREE.Raycaster(camera.position, ray);
// 返回射线选中的对象 第二个参数如果不填 默认是false
letintersects = rayCaster.intersectObjects(scene.children,true);
if(intersects.length >0) {
// console.log(intersects[0].object);
}
}
three.js raycaster射线碰撞的坑 (当canvas大小 不是屏幕大小是解决拾取物体的办法)的更多相关文章
- three.js的组合与合并,raycaster射线无法获取group
1.组合 创建一个组非常简单,在组中添加子元素的效果是,你可以对组进行移动.缩放和变形,而所有的子对象都会受到影响.使用组的时候,你依然可以引用.修改每一个单独的几何体.但是,使用raycaster射 ...
- 用js刷题的一些坑
leecode可以用js刷题了,我大js越来越被认可了是吧.但是刷题中会因为忽略js的一些特性掉入坑里.我这里总结一下我掉过的坑. 坑1:js中数组对象是引用对象 js中除了object还有数组对象也 ...
- JS连等赋值的坑
cnblogs标题: JS连等赋值的坑 关于JS连等赋值有个经典的笔试题: var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); ...
- Unity3D总结:关于射线碰撞
方法一:Physics.Raycast 光线投射 1.static function Raycast (origin : Vector3, direction : Vector3, distance ...
- js 根据屏幕大小调用不同的css文件
原因:屏幕大小不一样,网站看起来总觉得怪怪的,所以,针对不同大小的屏幕,写了不同的css,写完了,要解决的问题就是:怎么根据屏幕的大小来引用不同的CSS,下面就是解决方法了. 解决方法:首先,在hea ...
- js获取屏幕大小
1.js获取屏幕大小 <html> <script> function a(){ document.write( "屏幕分辨率为:"+screen.widt ...
- 怎么通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端?
今天在论坛上看到这样一个问题,有必要编辑搜集下. 问题描述:怎么通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端 题主用jquery接收 <input name= ...
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2 ...
- js/css 检测移动设备方向的变化 判断横竖屏幕
js/css 检测移动设备方向的变化 判断横竖屏幕 方法一:用触发手机的横屏和竖屏之间的切换的事件 window.addEventListener("orientationchange&qu ...
随机推荐
- mysql 忘记密码解决方案
Mysql 忘记root密码的完美解决方法 转载 2016-12-23 作者:MR.QiGao 我要评论 通常在使用Mysql数据库时,如果长时间没有登陆,或者由于工作交接完成度不高,会导 ...
- MD5加密和彩虹表
首先叙述一下彩虹表的原理.本部分内容.图片和例子基本来自英文维基的Rainbow table词条(Rainbow table)——中文维基中目前(2013年10月9日)尚无对应的词条——因此对本答案中 ...
- SQL思维导图总结
- h5内容初探
h5简介: h5新特性 h5新增标签 article 和 section 的区别相当于 div 和 p标签的区别 1—6都是块级元素 h5新增属性 拖放 拖动事件 <style> ...
- 弹窗切换page进行关闭
beforeRouteLeave(to,from,next){ //这里写关闭弹窗 // 这里跳转路由 MessageBox.close(); next() // next()别漏,不然不跳转 }
- Oracle 监听器日志解析
Oracle监听器是驻留在Oracle实例所在服务器上的独立进程.作为客户端进程连接实例的重要沟通组件,Oracle监听器扮演着重要的地位.本篇将从监听器日志入手,分析阅读监听器日志和日常监听器常见行 ...
- asyncio的核心概念与基本架构
https://blog.csdn.net/qq_27825451/article/details/86218230 虽然有部分运行错误,但是还是有参考价值.
- cmd从新获取ip
1.ipconfig/release 2.ipconfig/renew
- Python 函数内变量的作用域
Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域. 全局作用域(global):即在模块层次中定义的变量,每一个模块都是一个全局作用域 ...
- JPA in
CriteriaBuilder.In in = criteriaBuilder.in(root.get("field1")); for (String str : arr) { i ...