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轴作为相机旋转的旋转轴。

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



相关文章
|
8天前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
35 0
|
2天前
|
JavaScript API 数据库
深入理解Node.js事件循环及其在后端开发中的应用
【9月更文挑战第3天】本文将深入浅出地介绍Node.js的事件循环机制,探讨其非阻塞I/O模型和如何在后端开发中利用这一特性来处理高并发请求。通过实际的代码示例,我们将看到如何有效地使用异步操作来优化应用性能。文章旨在为读者揭示Node.js在后端开发中的核心优势和应用场景,帮助开发者更好地理解和运用事件循环来构建高性能的后端服务。
|
3天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【9月更文挑战第3天】本文将带你走进Node.js的世界,通过深入浅出的方式,让你了解Node.js的基本概念、特性以及如何在后端开发中应用。我们将从Node.js的安装开始,逐步深入到异步编程模型、事件驱动机制等核心概念,最后通过一个简单的Web服务器示例,让你对Node.js有一个全面的认识。无论你是前端开发者还是后端开发者,只要你对Node.js感兴趣,这篇文章都将为你打开一扇新的大门。
|
6天前
|
Kubernetes JavaScript Cloud Native
深入浅出Node.js后端开发
【8月更文挑战第31天】在数字化浪潮中,云原生技术如同星辰大海中的航船,引领企业乘风破浪。本文将带你从Docker容器的基础出发,探索至Kubernetes集群的奥秘,用代码示例点亮技术的灯塔,助你在云原生的海洋中找到属于自己的航道。
|
6天前
|
JavaScript 开发者
深入理解Node.js事件循环及其在后端开发中的应用
【8月更文挑战第31天】 本文将带你走进Node.js的事件循环机制,通过浅显易懂的语言和实例代码,揭示其背后的工作原理。我们将一起探索如何高效利用事件循环进行异步编程,提升后端应用的性能和响应速度。无论你是Node.js新手还是有一定经验的开发者,这篇文章都能给你带来新的启发和思考。
|
6天前
|
开发者 Java 存储
JSF 与 CDI 携手共进,紧跟技术热点,激发开发者情感共鸣,开启高效开发新征程
【8月更文挑战第31天】JavaServer Faces (JSF) 与 Contexts and Dependency Injection (CDI) 在 Java EE 领域中紧密协作,助力开发者高效构建现代 Web 应用。JSF 凭借其丰富的组件库和页面导航功能受到青睐,而 CDI 则优雅地管理对象生命周期并实现依赖注入。两者结合,不仅简化了复杂企业应用的开发,还实现了松耦合架构,增强了代码的灵活性、可维护性和可扩展性。通过示例展示了如何利用 CDI 将业务服务对象注入 JSF Managed Bean,以及如何在不同页面间共享数据,突显了这一组合的强大功能。
19 0
|
6天前
|
大数据 数据处理 分布式计算
JSF 逆袭大数据江湖!看前端框架如何挑战数据处理极限?揭秘这场技术与勇气的较量!
【8月更文挑战第31天】在信息爆炸时代,大数据已成为企业和政府决策的关键。JavaServer Faces(JSF)作为标准的 Java Web 框架,如何与大数据技术结合,高效处理大规模数据集?本文探讨大数据的挑战与机遇,介绍 JSF 与 Hadoop、Apache Spark 等技术的融合,展示其实现高效数据存储和处理的潜力,并提供示例代码,助您构建强大的大数据系统。
13 0
|
6天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【8月更文挑战第31天】在数字时代的浪潮中,Node.js以其非阻塞、事件驱动的特性,成为炙手可热的后端技术。本文将带你领略Node.js的魅力所在,从搭建开发环境到实战演练,我们用浅显易懂的语言和生动的例子,让你轻松掌握Node.js后端开发的精髓。无论你是新手还是有经验的开发者,这篇文章都将为你的技术之路添砖加瓦。
|
6天前
|
SQL 缓存 JavaScript
深入浅出Node.js后端开发
【8月更文挑战第31天】本文将带你走进Node.js的世界,从基础到进阶,逐步深入探讨如何在后端开发中利用Node.js的异步特性和丰富的库来构建高效、可扩展的应用。我们将通过实际代码示例,展示如何搭建一个简单的RESTful API,并讨论最佳实践和性能优化策略。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的知识和技能。
|
6天前
|
JavaScript 安全 数据安全/隐私保护
深入Node.js与Express:从表单接收到数据验证的完整指南——实战技巧揭秘后端开发中的表单处理流程
【8月更文挑战第31天】在Web开发中,处理表单数据至关重要。本文通过实例详细讲解了如何利用Node.js与Express框架接收和验证表单数据。首先,搭建环境并初始化一个简单的Express应用;接着,演示如何接收用户注册表单中的`username`和`email`字段;最后,引入`joi`模块进行数据验证,确保数据安全准确。掌握这些技能有助于开发者构建更安全、友好的Web应用。随着Node.js和Express的不断进步,未来将有更多高级功能值得期待。
14 0
下一篇
DDNS