当前位置: 首页 > news >正文

学习threejs,对模型多个动画切换展示

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.AnimationMixer 动画混合器
  • 二、🍀对模型多个动画切换展示
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中对模型多个动画切换展示,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.AnimationMixer 动画混合器

THREE.AnimationMixer动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。
创建方法:
AnimationMixer( rootObject : Object3D )
rootObject 是 混合器播放的动画所属的对象
属性:
time:Number 全局的混合器时间(单位秒; 混合器创建的时刻记作0时刻)。
timeScale:全局时间(mixer time)的比例因子。
说明: 将混合器的时间比例设为0, 稍后再设置为1,可以暂停/取消暂停由该混合器控制的所有动作。
方法:
clipAction(clip : AnimationClip, optionalRoot : Object3D):AnimationAction 返回所传入的剪辑参数的AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。
如果不存在符合传入的剪辑和根对象这两个参数的动作, 该方法将会创建一个。传入相同的参数多次调用将会返回同一个剪辑实例。
existingAction (clip : AnimationClip, optionalRoot : Object3D) : AnimationAction 返回传入剪辑的已有AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。
第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。
update (deltaTimeInSeconds : Number) : AnimationMixer 推进混合器时间并更新动画。
deltaTimeInSeconds 参数表示当前帧与前一帧之间的时间差(以秒为单位)。

二、🍀对模型多个动画切换展示

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.PointLight点光源,设置点光源位置,设置点光源投影,scene添加点光源。
  • 5、加载几何模型:创建THREE.AxesHelper坐标辅助工具,创建THREE.PlaneBufferGeometry平面几何体、THREE.GridHelper地板割线,scene场景中加入创建的平面几何体和地板割线。创建gui控件datGui。通过THREE.FBXLoader类加载 ‘Naruto.fbx’ 模型文件mesh,在加载模型的回调函数中,定义mesh动画,datGui加入动画控制。具体实现参考代码样例。
  • 6、加入controls控制,加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>learn50(对模型多个动画切换展示)</title><script src="lib/threejs/127/three.js-master/build/three.js"></script><script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script><!--<script src="lib/js/inflate.min.js"></script>--><script src="lib/threejs/127/three.js-master/examples/js/loaders/FBXLoader.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/fflate.min.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script><script src="lib/js/Detector.js"></script>
</head>
<style type="text/css">html, body {margin: 0;height: 100%;}canvas {display: block;}</style>
<body onload="draw()">
</body>
<script>var renderervar initRender = () => {renderer = new THREE.WebGLRenderer({antialias: true})renderer.setPixelRatio(window.devicePixelRatio)renderer.setClearColor(0xeeeeee)renderer.setSize(window.innerWidth, window.innerHeight)renderer.shadowMap.enabled = truedocument.body.appendChild(renderer.domElement)}var scenevar initScene = () => {scene = new THREE.Scene()scene.backgroundColor = new THREE.Color(0xa0a0a0)scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000)}var cameravar initCamera = () => {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)camera.position.set(100, 200, 300)}var lightvar initLight = () => {scene.add(new THREE.AmbientLight(0x444444))light = new THREE.DirectionalLight(0xffffff)light.position.set(0, 200, 100)light.castShadow = truelight.shadow.camera.top = 180light.shadow.camera.bottom = -100light.shadow.camera.left = -120light.shadow.camera.right = 120scene.add(light)}var gui, datGui, meshHelper, mixervar initGui = () => {gui = {helper: true}datGui = new dat.GUI()datGui.add(gui, 'helper').onChange(e => {meshHelper.visible = e})}var initModel = () => {var helper = new THREE.AxesHelper(50)scene.add(helper)var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({color: 0xffffff,depthWrite: false}))mesh.receiveShadow = truemesh.rotation.x = -0.5 * Math.PIscene.add(mesh)// var planeGeometry = new THREE.PlaneBufferGeometry(2000, 2000)// var planeMatarial = new THREE.MeshPhongMaterial({//   color: 0xffffff,//   depthWrite: false// })// var plane = new THREE.Mesh(planeGeometry, planeMatarial)// plane.rotation.x = -0.5 * Math.PI// plane.position.y = -0// plane.receiveShadow = true// scene.add(plane)// 添加地板割线var grid = new THREE.GridHelper(2000, 20, 0x000000, 0x000000)grid.material.opacity = 0.2grid.material.transparent = truescene.add(grid)var loader = new THREE.FBXLoader()loader.load('data/model/NarutoFbx/Naruto.fbx', mesh => {meshHelper = new THREE.SkeletonHelper(mesh)scene.add(meshHelper)mesh.traverse(child => {if (child.isMesh) {child.castShadow = truechild.receiveShadow = true}})mixer = mesh.mixer = new THREE.AnimationMixer(mesh)var actions = []var animations = datGui.addFolder('animations')var createAction = (i) => {actions[i] = mixer.clipAction(mesh.animations[i])gui['action' + i] = () => {for (var j = 0; j < actions.length; j++) {if (j === i) {actions[j].play()} else {actions[j].stop()}}}animations.add(gui, 'action' + i)}for (var i = 0; i < mesh.animations.length; i++) {createAction(i)}gui.stop = () => {for (var i = 0; i < actions.length; i++) {actions[i].stop()}}datGui.add(gui, 'stop')mesh.position.y += 100scene.add(mesh)})}var statsvar initStats = () => {stats = new Stats()document.body.appendChild(stats.dom)}var controlsvar initControls = () => {controls = new THREE.OrbitControls(camera, renderer.domElement)controls.enableDamping = true}var clock = new THREE.Clock()var render = () => {var time = clock.getDelta()if (mixer) {mixer.update(time)}controls.update()}var onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()render.setSize(window.innerWidth, window.innerHeight)}var animate = () => {render()stats.update()renderer.render(scene, camera)requestAnimationFrame(animate)}var draw = () => {initRender()initScene()initCamera()initGui()initLight()initModel()initStats()initControls()animate()window.onresize = onWindowResize}
</script>
</html>

效果如下:
在这里插入图片描述

http://www.lryc.cn/news/488311.html

相关文章:

  • 【Bug合集】——Java大小写引起传参失败,获取值为null的解决方案
  • Python爬虫:如何从1688阿里巴巴获取公司信息
  • 单片机学习笔记 2. LED灯闪烁
  • 折叠光腔衰荡高反射率测量技术的matlab模拟理论分析
  • ubuntu 16.04 中 VS2019 跨平台开发环境配置
  • C语言第13节:指针(3)
  • java:简单小练习,面积
  • @Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)
  • PostgreSQL提取JSON格式的数据(包含提取list指定索引数据)
  • 如何利用谷歌浏览器提高网络安全
  • go-zero(四) 错误处理(统一响应信息)
  • 1.1 爬虫的一些知识(大模型提供语料)
  • Linux开发工具:Vim 与 gcc,打造高效编程的魔法双剑
  • cesium for unity的使用
  • Android AOSP 架构和各层次开发内容介绍
  • Kafka 到 Kafka 数据同步
  • 华为刷题笔记--题目索引
  • osgEarth加载倾斜摄影测量数据
  • 消息推送问题梳理-团队管理
  • 如何在 Ubuntu 上使用 Docker 部署 LibreOffice Online
  • MongoDB数据备份与恢复(内含工具下载、数据处理以及常见问题解决方法)
  • 代码随想录第三十一天| 56. 合并区间 738.单调递增的数字
  • C语言基本知识 2.2void 函数
  • Spring 框架中哪些接口可以创建对象
  • 豆瓣书摘 | 爬虫 | Python
  • Oracle数据库物理存储结构管理
  • java——Map接口
  • 量子计算机全面解析:技术、应用与未来
  • IDEA相关(包括但不限于快捷键,使用技巧)成长笔记
  • 【再谈设计模式】适配器模式 ~接口兼容的桥梁