three.js 切割模型动画,并且播放

2023-10-29

因为公司没有人会用blender,所以动画都是用max做的,动画师一般都是会把多个动画做在一个模型上,然后程序中需要使用的话,调用指定的帧数。unity可以把动画切割成animationclip。最近公司使用了需要在three.js中添加一个模型,模型带了一段长动画,所以我这边就是需要把模型的指定帧数之间的动画切割出来。

接下来演示部分:

1.准备素材一段带动画的素材 

初始化,加入相机,灯光模型等元素

function init() {

      var canHeight = window.innerHeight;
      var canWidth = window.innerWidth;
      container = document.createElement('div');

      camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
      camera.position.set(0, 150, 300);
      scene = new THREE.Scene();

      // ground
      var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }));
      mesh.rotation.x = - Math.PI / 2;
      mesh.receiveShadow = true;
      scene.add(mesh);

      var grid = new THREE.GridHelper(2000, 20, 0x000000, 0x000000);
      grid.material.opacity = 0.2;
      grid.material.transparent = true;
      scene.add(grid);

      renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
      });

      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.shadowMap.enabled = true;
      container.appendChild(renderer.domElement);

      controls = new THREE.OrbitControls(camera, renderer.domElement);
      controls.target.set(0, 100, 0);
      controls.update();
      LoadModel();
      LoadLightModel();
      document.getElementById("threejsContainer").appendChild(renderer.domElement);
      window.addEventListener('resize', onWindowResize, false);
    }

    function LoadLightModel() {
      scene.background = new THREE.Color(0xa0a0a0);
      light = new THREE.HemisphereLight(0xffffff, 0x444444);
      light.position.set(0, 200, 0);
      scene.add(light);

      light = new THREE.DirectionalLight(0xffffff);
      light.position.set(0, 200, 100);
      light.castShadow = true;
      light.shadow.camera.top = 180;
      light.shadow.camera.bottom = - 100;
      light.shadow.camera.left = - 120;
      light.shadow.camera.right = 120;
      scene.add(light);

    }


    function LoadModel() {
      var femaleModel = new THREE.FBXLoader();
      femaleModel.load('../Model/Female_Match_Animation_H5.FBX', (object) => {
        object.scale.set(100, 100, 100);
        object.traverse(function (child) {

          if (child.isMesh) {
            if (child.name === 'head_base') {
              child.visible = false;
            }
            if (child.name === 'female_body_gai001') {
              child.material = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('../Model/map/female_body.jpg'),
                skinning: true,
                color: 0xffffff,
                side: THREE.DoubleSide
              });
            }
            if (child.name === 'female_head_26') {
              for (var i = 0; i < child.material.length; i++) {
                if (child.material[i].name === 'head_bozi_female_26_small_Std_Skin_Head') {
                  child.material[i] = new THREE.MeshBasicMaterial({
                    map: new THREE.TextureLoader().load(
                      '../Model/map/female_head_26.png'
                    ),
                    skinning: true,
                    color: 0xffffff,
                    morphTargets: true,
                    side: THREE.DoubleSide

                  });
                }

                if (child.material[i].name === 'Eyelash') {
                  child.material[i] = new THREE.MeshBasicMaterial({
                    map: new THREE.TextureLoader().load(
                      '../Model/map/female_Eyelash.png'
                    ),
                    skinning: true,
                    color: 0xffffff,
                    transparent: true,
                  });
                }
                if (child.material[i].name === 'Eye') {
                  child.material[i] = new THREE.MeshBasicMaterial({
                    map: new THREE.TextureLoader().load(
                      '../Model/map/female_eye.png'
                    ),
                    skinning: true,
                    color: 0xffffff,
                  });

                }
              }
            }
          }
        });
        model = object;
        scene.add(object);
      });

    }

导入模型之后如上图所示,这个时候并没有执行模型的动画,所以他就是没有动画的状态

2.切割three.js 需要使用的是THREE.AnimationUtils.subclip这个方法

我这边需要的是动作每一个动作的姿势,所以我只切割了一帧。如果大家需要的是一个动作的话就可以根据需要来切割

 function SetModelAnimationClip(action) {
      console.log(action)
      mixer = new THREE.AnimationMixer(model);
      var modelaction = model.animations[0];
      if (actionList.length == 0) {

        actionList.actionA = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'A', 59, 60));
        actionList.actionB = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'B', 129, 130));
        actionList.actionC = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'C', 199, 200));
        actionList.actionD = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'D', 270, 271));
        actionList.actionE = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'E', 399, 400));
        actionList.actionF = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'F', 529, 530));
        actionList.actionG = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'G', 599, 600));
        actionList.actionH = mixer.clipAction(THREE.AnimationUtils.subclip(modelaction, 'H', 668, 669));

      }
      actionClip = actionList['action' + action];
      actionClip.play();

    }

这里我把这些切割玩的动画放在了一个actionList中,以后需要调用的时候直接使用就可以了。

3.在界面中添加一些按钮这样就可以直接切换动作了

切换不同的动作。

 

遇到的问题:一开始我只引用了three.js这个脚本(单独的),在使用THREE.AnimationUtils.subclip这个方法的时候无法执行,代码也不会报错。可能是脚本插件不齐全吧,所以我用了我在vue中下载的比较完整的three的插件。

下载地址:https://download.csdn.net/download/AlZhuo/13577173

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

three.js 切割模型动画,并且播放 的相关文章

  • 防止浮动换行,直到元素达到最小宽度

    我有可变宽度的 HTML 布局 内容左侧有一个固定宽度的菜单 div 可变宽度 由 css max width 和 min width 设置 对于非常窄的浏览器窗口 我希望内容包裹在菜单下方 我目前通过设置来实现这一点float left在
  • Jquery 中的动态滚动位置

    请帮助我解决以下情况 我有 3 个页面 当滚动到达第二页时 用户滚动页面 它必须找到特定的 ID 然后触发一个函数 一旦第三页开始 另一个函数就会触发 根据要求我不应该使用任何插件
  • 使用 JS 合并具有相同值的相邻 HTML 表格单元格

    我已经为此苦苦挣扎了一段时间 我有一个根据一些 JSON 数据自动生成的表 该数据可能会有所不同 我想合并第一列中具有相同值的相邻单元格 例如此表中的 鱼 和 鸟 table tr td fish td td salmon td tr tr
  • 我可以停止 :hover 应用于元素吗?

    假设我有一些 CSS button hover font weight bold 我怎样才能防止 hover随意应用样式 我的目标用例是当元素被禁用时 例如 使用这个 HTML
  • 为什么“tbody”不设置表格的背景颜色?

    我在用 tbody 作为 CSS 选择器来设置background color在一个表中 我这样做是因为我有多个 tbody 表内的部分 它们具有不同的背景颜色 我的问题是 当使用border radius在细胞上 细胞不尊重backgro
  • 悬停时为 SVG 制作动画

    我正在尝试在悬停时为 SVG 文件设置动画 默认情况下 它可以使用 svg 函数实现出色的动画效果 例如
  • 防止文本区域出现新行

    我正在开发聊天功能 使用 Vue 并使用文本区域作为输入 以便溢出换行 并且对于编写较长消息的用户来说更具可读性 不幸的是 当用户按下 Enter 键并提交时 光标会在提交之前移动到新行 从而使用户体验感觉不佳 关于如何使用普通 Javas
  • XHTML 和 HTML 类属性值可以以数字开头吗?

    XHTML 和 HTML 类属性值可以以数字开头吗 No 它们必须是 SGML 名称 http www w3 org TR REC html40 types html type cdata它们 必须以字母 A Za z 开头 后跟任意数量的
  • jQuery:查找文本并替换为 HTML

    我尝试查找并替换文本 使用 jQuery 实际上我正在尝试在文本周围添加一个 span 元素 我还应该能够再次删除跨度而不会丢失里面的文本 例如 假设我有以下情况 span This is a span element span 我希望能够
  • 如何使按钮在表格单元格内居中

    我试图通过以下方式将按钮置于表格内的中心 text align center 然而 它似乎对我不起作用 注 我用过Display table cell结合Vertical align middle将按钮的文本居中 正如您所看到的 第一个按钮
  • 上传图像 onclick 多个蒙版图像

    一旦用户单击蒙版图像 我们就允许用户上传自定义图像 如果有单个蒙版图像 则效果很好 https codepen io kidsdial pen jJBVON https codepen io kidsdial pen jJBVON 要求 但
  • scrollWidth/scrollHeight 给出无效尺寸

    如所述https developer mozilla org en Determining the dimensions of elements https developer mozilla org en Determining the
  • 具有有限行数和字符数限制的文本区域

    我需要具有 TextArea 的功能 1 maximum total lines 6 and 2 in each line there must be maximum of 16 chars 3 if user enters 17th ch
  • 多少个 div 标签太多了?

    在一个 HTML 文档中需要多少个 div 标签才会影响性能 在这种情况下 标签不嵌套 并且每个标签内的内容最少 背景颜色 图像 这个问题是上一个问题的后续问题 使用 JavaScript 绘制带有可点击点的线条 https stackov
  • 将一个文本框的内容复制到另一个文本框

    假设在文本框中输入了一个条目 是否可以在第二个文本框中保留相同的输入文本 如果是这样 这是如何完成的
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • iframe 重新加载按钮

    我浏览了很多网站 但似乎没有一个能正常工作 或者我不明白它们 我想要一个刷新某个 iframe 的简单按钮 该按钮将位于父页面上 并且 iframe 名称为 Right 有很多方法可以做到这一点 假设这个iframe markup 我们可以
  • 使用 jquery 将字符串数组转换为整数

    我正在尝试将 jquery 中的字符串数组转换为整数数组 这是我的尝试 var cdata data values split each cdata function i l l parseInt l 我认为在这种情况下你不需要使用 Jqu
  • 电话号码上未拾取结构化数据

    我在网站上有以下代码片段 当我通过 Google 结构化数据测试工具运行此程序时 它不会获取电话号码 我不确定我哪里错了 div class telephone number p Call Us a href 07749 918 143 a
  • span 和 iframe 正文中的宽度(以像素为单位)

    我需要知道 a 的宽度 nbsp 以像素为单位 以及是否取决于字体大小 另外 页面中不同元素的情况是否有所不同 还有 就是 nbsp 与常规不同 目的 nbsp 不间断空格 位于正常空格之上是为了防止单词之间出现换行 您可以使用多个 nbs

随机推荐

  • 用apache james做简单的垃圾邮件过滤网关(转)

    网络环境如下 三台服务器 1 网关 公网IP 2 domino邮件服务器 3 另一台服务器 通过把网关的端口25 映射到domino服务器上 让domino服务器可以收发邮件 同时domino服务器还要把部分邮件转发到服务器3上 大家的发邮
  • 801冠号大全及桃花荧光

    第一 存量少是801升值的基本依据 801共158个冠号 天蓝 荧光 冠号去除一部分 桃花荧光油墨的占到801的总量的80 以上 有荧光满版网格的又分为 1 满版红桃花荧光 满版底纹网格荧光 2 满版金桃花荧光 满版底纹网格荧光 3 满版桃
  • JavaWeb——SSJDBC(struts2,spring,jdbc)框架,正向工程

    原文地址 http blog csdn net sapce fish article details 52900750 本文采用struts2 spring jdbc搭建web框架 使用正向工程 IDE用myeclipse 数据库用Mysq
  • 实时汇率转换小程序(c++爬虫)

    实时汇率转换小程序 c 爬虫 利用c 网络爬虫爬取网页的实时汇率进行汇率的转换 其中也利用了QT进行了页面设计 define SILENCE STDEXT HASH DEPRECATION WARNINGS include
  • Linux下安装过程中编译PHP时报错:configure: error: jpeglib.h not found.

    今天在搭建LNMP编译PHP时 报错 configure error jpeglib h not found root cac3 php 5 6 22 configure gt prefix usr local php5 gt enable
  • Java Thread Join

    join方法的作用 在A线程中调用了B线程的join 方法时 表示只有当B线程执行完毕时 A线程才能继续执行
  • Opencv之答题卡识别判卷

    项目要求 提供一张答题卡图像 通过图像处理识别出答题卡上每个题的选项 与正确答案对比 得出分数并写在答题卡上 代码实现过程 1 引入需要的库 import numpy as np import cv2 as cv 2 定义绘图函数 def
  • 下代码下代码下代码

    https modelzoo co
  • linux c语言编译成exe,C/C++程序从编译到最终生成可执行文件的过程分析

    C C 程序编译步骤 如何生成可执行文件 电子计算机所使用的是由 0 和 1 组成的二进制数 二进制是计算机的语言的 基础 计算机发明之初 人们只能降贵纡尊 用计算机的语言去命令计算机干这干那 一 句话 就是写出一串串由 0 和 1 组成的
  • QT事件--阐述的比较系统

    转载 http www qtcn org bbs simple t31383 html Another Look at Events 再谈Events 最近在学习Qt事件处理的时候发现一篇很不错的文章 是2004年季刊的一篇文章 网上有这篇
  • 迷宫 蓝桥杯 641

    题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 X 星球的一处迷宫游乐场建在某个小山坡上 它是由 10 1010 10 相互连通的小房间组成的 房间的地板上写着一个很大的字母 我们假设玩家是面朝上坡的方向站
  • 单链表的应用(多项式相加)

    目录 题目内容 算法分析 概要设计 流程图 代码块 运行结果 题目内容 完成两个多项式的相加操作 已知有两个多项式Pm x Qm x 设计算法实现Pm x Qm x 运算 而且对加法运算不重新开辟存储空间 要求用链式存储结构实现 例如 Pm
  • 进程的互斥与同步

    一 进程 线程的背景 引入进程 为了描述和实现多个程序的并发执行 以改善资源利用率即提高系统的吞吐量 引入线程 减少程序并发执行时系统所付出的额外开销 使操作系统具有更好的并发性 二 进程的互斥与同步 注意 同步即协调 采用多道程序技术的操
  • xss.haozi.me靶场详解

    xss haozi me靶场详解 前言 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 前言 由于
  • sqli-labs靶场challenges第54-75关(超详细)

    目录 第五十四关 单引号闭合 第五十五关 括号闭合 第五十六关 单引号 括号闭合 第五十七关 双引号闭合 第五十八关 单引号闭合报错注入 第五十九关 数字型报错注入 第六十关 双引号 括号闭合 第六十一关 单引号 双括号闭合报错注入 第六十
  • 通过资源本地化技术减少Flink在YARN上的部署时间

    在大数据领域中 Apache Flink是一个流式处理和批处理的开源框架 能够处理高容量和高速度的数据流 在使用Flink时 通常会将其部署在基于YARN Yet Another Resource Negotiator 的集群上 以便充分利
  • win10环境配置jdk8和jdk17切换失效已解决

    配置jdk8环境变量 1 打开环境变量 在系统变量中新建 变量名为JAVA HOME 变量值为jdk8的安装路径D java package jdk8 2 在系统变量中新建 变量名为CLASSPATH 变量值为 JAVA HOME lib
  • 隐私计算和联邦学习发展的举措

    建立大数据隐私计算和联邦学习生态联盟 联邦学习的新商业模式需要一个商业联盟 联盟包含有 N 个实体 加入联盟的实体 可以像朋友圈一样能够利用各自的数据联合建立模型 联邦数据联盟鼓励各方参与 联盟成员一方面进行垂直领域的合作 另一方面 联盟有
  • Centos7安装vmware-tools教程

    一 前言 本教程同样适用Ubuntu系统 虽有些许不同 但总体思路不变 二 安装 1 挂载vmware tools 2 SSH连接Centos虚拟机 ssh root 192 168 2 2 3 创建CD DVD挂载路径 root loca
  • three.js 切割模型动画,并且播放

    因为公司没有人会用blender 所以动画都是用max做的 动画师一般都是会把多个动画做在一个模型上 然后程序中需要使用的话 调用指定的帧数 unity可以把动画切割成animationclip 最近公司使用了需要在three js中添加一