Three.js开发秘籍:FlyControls的拖拽视角问题解决方案

简介: Three.js开发秘籍:FlyControls的拖拽视角问题解决方案

需求背景

工作中需要使用 threejs 制作一个第一人称的 viewer,在使用 threejsflyControls 时发现一些和需求不一样的情景。

主要的问题就是拖拽查看时相机在拖拽后会导致上方向的变化从而导致视角变化很奇怪,所以需要改造一下原本的 FlyControl

既然要改造那就肯定要先解析 FlyControls 的源码了

FlyControls的功能

FlyControls 实现了一个类似第一人称视角通过 WASD 来调整相机前进的基本控制器。

例子threejs.org/examples/#m…

文档threejs.org/docs/index.…

可以看到上图 WASD 控制移动,RF 控制上下移动,QE 旋转相机,方向键上下左右可以控制视角。

也可以用鼠标偏移位置自动旋转视角

源码分析属性声明

地址

github.com/mrdoob/thre…

首先 FlyControls 继承自 EventDispatcherEventDispatcher 是事件调度器。

主要是用于 FlyControls 的事件信息传递用。

构造函数中一个是 object 也就是控制的摄像机对象从 TS 定位文件中可以看出是一个Camera或者继承自Camera的对象。

domElement 则是当前 threejs renderer 绘制的 dom 元素

接下来就是一系列变量的定义

其中 movmentSpeedrollSpeed 是控制相机移动和旋转的速度的

dragToLook 则是我们需求中需要的拖拽使相机视角发生变化,可以看到这里默认是 false

autoForward 是自动向前

EPS 应该是最小误差修正用的

可以看到这里还用 lastQuaternionlastPosition 记录了最后相机的四元组和位置信息

tmpQuaternion 就是临时保存用的一个四元组

剩下就是一些状态值

源码分析事件监听

在代码最底部可以看到 FlyControls 监听了7个事件分别对应一系列操作。

先从第一个keydown分析

1、一开始判断是否按下了 alt 键和是否启用了控制器

2、然后根据按键的键码分别设置 moveState 的状态,其中 shift 对移动速度进行了修改

3、然后就是最关键的 updateMovementVectorupdateRotationVector,这两个之后进行分析。

这里 keyupkeydown 类似就不过多做分析

然后是鼠标操作三兄弟

pointerdown 可以看出来是根据 dragToLook 来进行不同的操作。

如果是拖拽调整视角就修改 status 的值

如果不是则根据按下的鼠标左键还是又键修改 moveState 的状态。

紧接着pointermove事件中

依旧如果不是使用拖拽查看或者 status大于0 (这里的 status>0 是由向前的 pointerdown 修改的,也就是可以看做是否按下了鼠标)

然后就是这个 getContainerDimensions ,其实就是查看这个当前的 viewer 是不是在 docment 对象,返回相应的大小和偏移值

halfWidthhalfHeight 就是当前 viewer 可视区域一半的宽高。

-( event.pageX - container.offset[ 0 ] ) ( ( event.pageY - container.offset[ 1 ] )是鼠标在当前可视区域的相对坐标,

其值减去一半的宽度后,其实就可以视作鼠标相对于可视区域中心点的相对位置了。

x轴来举例可以看出来 ( event.pageX - container.offset[ 0 ] ) - halfWidth 则是红线部分则是鼠标到中心点的距离。

然后除以 halfWidth 则是一个归一化处理,相当于把鼠标距离中心点位置的值域控制在0到1之间了,最后在修改 moveState

最后pointerup事件则是将状态还原

在此之后 可以看到 updateMovementVectorupdateRotationVector  实质上是修改了 moveVector 和  rotationVector

最后

再根据之前设置的速度和旋转值以及 rotationVectormoveVector 来控制相机的位置以及旋转。

最后的判断则是看移动和旋转的值是否太小了。

太小就进行忽略。

分析

那么这个控制器为什么会造成拖拽后上方向发生变化呢,其实从上面代码的分析不难看出。

先将鼠标向上旋转一个角度

再将鼠标朝右旋转

最后再朝下拖动鼠标时

此时的相机左方向轴已经不在x轴与y轴构成的平面上了。

所以相机上方向发生了变化。

其根本原因是相机左右旋转时旋转轴是以自身上方向为旋转轴造成的。

如果要保持相机上方向一致的情况下旋转视角应该以z轴作为相机旋转的旋转轴。

这样相机怎么旋转都能保持上方向一致了。



相关文章
|
6天前
|
Web App开发 缓存 JavaScript
深入浅出Node.js后端开发
【9月更文挑战第26天】本文将引导你了解Node.js的基本原理,并通过实际案例展示如何在后端开发中应用它。我们将从Node.js的核心概念讲起,逐步深入到构建一个完整的后端服务,最后探讨如何优化你的Node.js应用。准备好让你的开发技能更上一层楼了吗?让我们一起潜入Node.js的世界!
|
9天前
|
JavaScript 前端开发 API
深入浅出Node.js后端开发
【9月更文挑战第23天】在这篇文章中,我们将探索Node.js的世界,了解它如何改变后端开发的面貌。通过实际案例和代码示例,我们不仅学习Node.js的核心概念,还会深入探讨它的高级特性,如异步编程、事件驱动模型以及微服务架构的应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和实用技能,帮助你构建更高效、可扩展的后端系统。
41 19
|
7天前
|
JavaScript 开发者
深入理解Node.js事件循环及其在后端开发中的应用
【8月更文挑战第57天】本文将带你走进Node.js的事件循环机制,通过浅显易懂的语言和实例代码,揭示其背后的工作原理。我们将一起探索如何高效利用事件循环进行异步编程,提升后端应用的性能和响应速度。无论你是Node.js新手还是有一定经验的开发者,这篇文章都能给你带来新的启发和思考。
|
5天前
|
Web App开发 JavaScript 前端开发
探索现代JavaScript开发:ECMAScript提案的未来
JavaScript是最受欢迎的编程语言之一,其发展迅速。ECMAScript(JS的标准化版本)的提案和更新为其带来了诸多新特性和改进。本文将介绍值得关注的ECMAScript提案,如可选链、空值合并运算符、逻辑赋值运算符、类字段和顶级Await,并展示如何利用这些新特性提升开发效率和代码质量。通过关注TC39提案流程、使用Babel和TypeScript等工具,开发者可以提前体验并利用这些新特性。随着JavaScript的不断进步,未来将有更多令人期待的功能加入。
|
7天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【9月更文挑战第25天】本文将带你了解Node.js的基本概念和核心优势,同时提供一些实际的代码示例来加深理解。无论你是初学者还是有一定经验的开发者,都能通过本文获得有价值的信息和技巧。让我们一起探索Node.js的世界吧!
|
9天前
|
JavaScript 前端开发
js防抖函数返回值问题解决方案
本文介绍了如何在JavaScript中创建一个带有返回值的防抖函数,通过结合Promise来实现。这种防抖函数可以在事件触发一定时间后再执行函数,并能处理异步操作的返回值。文章提供了防抖函数的实现代码和如何在实际项目中使用该防抖函数的示例。
16 1
|
18天前
|
Web App开发 存储 JavaScript
深入浅出Node.js后端开发
【9月更文挑战第15天】在数字化浪潮中,Node.js作为一颗耀眼的星辰,为后端开发领域注入了活力与创新。本文将带你领略Node.js的魅力所在,探索其架构设计、性能优化及实战应用,让你在轻松愉快的氛围中掌握Node.js后端开发的精髓。
|
21天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【9月更文挑战第11天】本文将带你走进Node.js的世界,了解其背后的运行机制和实际应用。我们将从基础概念出发,逐步深入到实战应用,最后通过代码示例巩固学习成果。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和思考。
|
20天前
|
JavaScript 前端开发 API
深入浅出Node.js后端开发
【9月更文挑战第13天】本文将带你进入Node.js的世界,从基础概念到实际案例,深入浅出地探讨如何利用Node.js进行后端开发。通过本文的学习,你将了解Node.js的工作原理、核心模块、以及如何构建一个简单的Web应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
21天前
|
Web App开发 JavaScript NoSQL
深入浅出Node.js后端开发
在数字化时代的浪潮中,后端开发作为技术支柱之一,承载着数据处理和业务逻辑实现的重要任务。本文将通过浅显易懂的方式,带你走进Node.js的世界,从基础概念到实战应用,逐步揭开后端开发的神秘面纱。无论你是编程新手还是希望扩展技术栈的开发者,这篇文章都将为你提供有价值的指导和启示。让我们一起探索如何在不断变化的技术环境中,保持初心,寻找属于自己的方向,并成为希望在世界上看到的改变。
31 1
下一篇
无影云桌面