Three.js杂记(十五)—— 汽车展览(下)

在上一篇文章Three.js杂记(十四)—— 汽车展览·上 - 掘金 (juejin.cn)中主要对切换相机不同位置和鼠标拖拽移动相机焦点做了简单的应用。

那么现在聊聊该如何实现汽车模型自带的三种动画展示了,实际上可以是两种汽车前后盖打开汽车4车门打开,最后一种只是将前两种结合起来了。

关于ThreeJs中动画可以参考:

  • 官方API文档:AnimationAction – three.js docs (threejs.org)
  • ThreeJs中文网:1. 关键帧动画 | Three.js中文网 (webgl3d.cn)

模型动画运行

ThreeJs动画是关键帧动画,在汽车模型导入时,可以从gltf中查找到AnimationClip动画剪辑。

在查找动画这一步上面,我卡了很久,一直没找到动画。原因是我从gltf.sceneanimations上开始查找的,没有找到,甚至还递归遍历内部元素寻找animations。但是最后发现,直接gltf.animations就可以找到三种动画,白白绕了一大圈。

在这里插入图片描述

找到模型动画后,使用AnimationMixer函数生成一个动画混合器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。

接下来将gltf.scene关键帧动画模型的父对象作为参数传入。获得混合器实例mixerclipAction方法获取获取动画剪辑,然后使用play方法播放此动画。可以对循环次数进行限制。

gltfLoader.load中添加以下代码:

// 模型动画
const modelAnimationArr = gltf.animations;
//包含关键帧动画的模型作为参数创建一个播放器
mixer = new THREE.AnimationMixer(gltf.scene);
const clipAction = mixer.clipAction(modelAnimationArr[0]);
clipAction.play(); //播放动画
//不循环播放
clipAction.loop = THREE.LoopOnce; 

当然,现在动画还是不会生效。因为没有执行混合器的update方法,推进混合器时间并更新动画。需要在animate中进行添加,可以使用ThreeJsClock时钟,用于跟踪时间,当然也可以直接使用new Date()

// 如果想播放动画,需要周期性执行`mixer.update()`更新AnimationMixer时间数据
const clock = new THREE.Clock();
function animate() {if (mixer) {//clock.getDelta()方法获得loop()两次执行时间间隔let frameT = clock.getDelta();// 更新播放器相关的时间mixer.update(frameT);}// ...
}

这样一来,汽车第一个动画效果就运行起来了。

在这里插入图片描述


三种动画切换

在成功运行了第一种动画后,接下来就只是一些完善性的工作了。

在原先的面板上添加三种动画的切换按钮吧。

在这里插入图片描述

然后动画的切换比较重要,这里官网API:AnimationAction – three.js docs (threejs.org)

  1. 对于当前所属动画可以设置curIndex,然后如果动画尚未结束,那么先用stop方法结束动画
  2. 判断动画是否结束,可以在混合器上绑定finished监听事件。在动画事件结束之后,重新将curIndex设置为-1
  3. 动画启动时,设置curIndex的值为当前动画的index序号,然后使用play函数进行播放。
  4. 根据我的观察,当前汽车模型的动画最后会把打开的车门又关闭,但是我不希望关闭,可以设置剪辑对象的结束时间,并通过clampWhenFinished让动画停止在最后一帧。
// 切换改变当前汽车动画
let curIndex = -1;
const changeAnimation = (num: number) => {if (curIndex > -1) {// 结束原先动画mixer.clipAction(modelAnimationArr[curIndex]).stop();}curIndex = num;const clipAction = mixer.clipAction(modelAnimationArr[num]);clipAction.time = 2;  // 剪辑对象起始时间clipAction._clip.duration = 10; //剪辑对象设置播放结束时间clipAction.clampWhenFinished = true; // 是否在动画结束时停止播放clipAction.play(); //播放动画//不循环播放clipAction.loop = THREE.LoopOnce; mixer.addEventListener( 'finished', function(e:any) {curIndex = -1;});
}

效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础:探秘基本数据类型与对象的巧妙转换

作为准备面试的程序员,了解Java的基本数据类型及其与对象之间的转换功能是非常重要的。 本文将深入探讨Java的基本数据类型,介绍基本数据类型和对象之间的转换方式,帮助你更好地准备面试。 Java的基本数据类型 Java的基本数据类型包括以下…

抑郁后的症状表现——XWX-QP大小鼠强迫游泳桶硬件

简单介绍: 大小鼠强迫游泳桶硬件主要用于抗抑郁的研究。适用于大鼠、小鼠或其他实验室动物,通过将实验动物置于一个局限的环境中,动物在该环境中拼命挣扎试图逃跑又无法逃脱,从而提供了一个无可回避的压迫环境,动物的…

如何提取二维码文本信息?文本二维码提取内容的方法

如何分解出二维码中的文本信息呢?很多商家在做活动时会给每个用户生成一个单独的二维码,每一个二维码中有单独的编号信息,那么当我们收集到用户的二维码时,如何操作才能够提取二维码中的编号信息呢?想要解决这个问题可…

双目深度估计原理立体视觉

双目深度估计原理&立体视觉 0. 写在前面1. 双目估计的大致步骤2. 理想双目系统的深度估计公式推导3. 双目标定公式推导4. 极线校正理论推导 0. 写在前面 双目深度估计是通过两个相机的对同一个点的视差来得到给该点的深度。 标准系统的双目深度估计的公式推导需要满足:1)两…

Vue3+ts(day04:watch、watchEffect)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学,可以点心心支持一下哈(笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】,记录一下学习笔记,用于自己复盘,有需要学…

机器学习学习 - 数据预处理

机器学习学习笔记 - 数据预处理 数据预处理是机器学习项目中不可或缺的一环,它涉及到数据的清洗、格式化、归一化、特征提取等一系列操作,以便为后续的模型训练和分析提供高质量的数据集。以下是关于数据预处理的一些关键步骤和注意事项。 一、数据准备…

树莓派5用docker运行Ollama3

书接上回,树莓派5使用1panel安装 Ollama 点击终端就可以进入容器 输入以下代码 ollama run llama3Llama3 是市场推崇的版本。您的 树莓派5上必须至少有 4.7GB 的可用空间,因此用树莓派玩机器学习就必须配置大容量的固态硬盘。用1panel部署网络下载速度…

RTX3090显卡功耗对比

NVIDIA RTX 3090显卡的官方总图形功耗(TGP)为350瓦。这是公版显卡的设计功耗。然而,在实际使用中,尤其是进行高强度任务如游戏或专业渲染时,其功耗可能会超过这个数值,尤其在超频的情况下。有报告指出&…

vue-cli+vue3+vite+ts 搭建uniapp项目全过程(二)

接上一篇 3、别名配置 代替 ./srccomponents代替./src/components 在 Vite 中, __dirname 并不是一个全局变量,所以在vite.config.ts 文件中无法直接使用。 安装依赖 npm install --save-dev types/node vite.config.ts配置 // vite.config.t…

Python | Leetcode Python题解之第58题最后一个单词的长度

题目: 题解: class Solution:def lengthOfLastWord(self, s: str) -> int:ls[]for i in s.split():ls.append(i)return len(ls[-1])

跟TED演讲学英文:The future will be shaped by optimists by Kevin Kelly

The future will be shaped by optimists Link: https://www.ted.com/talks/kevin_kelly_the_future_will_be_shaped_by_optimists Speaker: Kevin Kelly Date: August 2021 文章目录 The future will be shaped by optimistsIntroductionVocabularyTranscriptSummary后记 In…

Verilog基础语法——状态机(类型、写法、状态编码方式)

Verilog基础语法——状态机(类型、写法、状态编码方式) 写在前面一、状态机类型二、状态机写法2.1 一段式2.2 两段式2.3 三段式 三、状态机状态编码方式写在后面 写在前面 在FPGA设计过程,经常会设计状态机用于控制整个硬件电路的工作进程&am…

基于Vue3的Axios异步请求

基于Vue3的Axios异步请求 1. Axios安装与应用2. Axios网络请求封装3. axios网络请求跨域前端解决方案server.proxy 1. Axios安装与应用 Axios是一个基于promise的网络请求库,Axios.js.中文文档:https://axios.js.cn/ 安装:npm install --sa…

CM3:qemu执行汇编

正文 环境:macOS M1。 前文讨论了 qemu 模拟8086 的平台运行8086 汇编代码,本文将讨论 qemu 模拟arm 平台运行 CM3 代码。代码: .syntax unified .cpu cortex-m3.global _start.equ UART0_BASE, 0x4000C000 .equ UART0_DR, UART0_BASE 0x0…

有没有一种可能性,你不投递简历,让HR主动联系你

你是否觉得自己得主动给某个公司投递了简历,他们才会联系你,亦或者是自己得主动在招聘APP上联系那个BOSS,他才会反过来跟你说话,又或者是你千方百计的跟他打招呼了,还是没有回应,这一节有可能让你明白,有时候是可以,你不主动,他也会主动联系你的。 目录 1 简历是如何…

蛋白质相互作用

STRING数据库简介 STRING是一个包含已知和预测蛋白质-蛋白质相互作用的数据库。数据库涵盖了直接(物理)和间接(功能)相互作用。包含来自实验仓库、计算预测方法和公共文本集合的多种证据来源。覆盖超过2400万个蛋白质,涉及5090个生物体。提供R包STRINGdb以方便用户从R访问…

QT:小项目:登录界面 (下一个连接数据库)

一、效果图 登录后&#xff1a; 二、项目工程结构 三、登录界面UI设计 四主界面 四、源码设计 login.h #ifndef LOGIN_H #define LOGIN_H#include <QDialog>namespace Ui { class login; }class login : public QDialog {Q_OBJECTpublic:explicit login(QWidge…

Spark原理之Cache Table的工作原理及实现自动缓存重复表的思考

CACHE TABLE的能力 使用此语法&#xff0c;可以由用户自定义要缓存的结果集&#xff0c;实际上就是一个临时表&#xff0c;不过数据存储在Spark集群内部&#xff0c;由Application所分配的executors管理。 一旦定义了一个缓存表&#xff0c;就可以在SQL脚本中随处引用这个表名…

Ansible自动化运维工具主机清单配置

作者主页&#xff1a;点击&#xff01; Ansible专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月24日12点21分 Ansible主机清单文件用于定义要管理的主机及其相关信息。它是Ansible的核心配置文件之一&#xff0c;用于Ansible识别目标主机并与其建立连接。 …

小猫咪邮件在线发送系统源码v1.1,支持添加附件

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 小猫咪邮件在线发送系统源码v1.1&#xff0c;支持添加附件 一款免登录发送邮件&#xff0c;支持发送附件&#xff0c;后台可添加邮箱,前台可选择发送邮箱 网站数据采取本地保存&…