zoukankan      html  css  js  c++  java
  • three.js 自制骨骼动画(二)

    上一篇说了一下自制骨骼动画,这一篇郭先生使用帧动画让骨骼动画动起来。帧动画是一套比较完善的动画剪辑方法,详细我的api我们就不多说了,网上有很多例子,自行查找学习。在线案例请点击博客原文。话不多说先上图。

    1. 初始化一些四元数

    首先我们需要一些四元数,因为我们的动画里有很多旋转并且帧动画的旋转要求是四元数。

    et q1 = this.getQuater(0,0,-Math.PI/4)
    let q2 = this.getQuater(0,0,Math.PI/3)
    let q3 = this.getQuater(0,0,-Math.PI/2)
    let q4 = this.getQuater(0,0,0)
    let q5 = this.getQuater(0,0,Math.PI/4)
    let q6 = this.getQuater(0,0,Math.PI/3)
    let q7 = this.getQuater(0,Math.PI/4,Math.PI/12)
    let q8 = this.getQuater(0,0,-Math.PI/6)
    let q9 = this.getQuater(0,-Math.PI/4,Math.PI/12)
    let q10 = this.getQuater(0,Math.PI/12,0)
    let q11 = this.getQuater(0,-Math.PI/12,0)
    
    getQuater(x,y,z) {
        return new THREE.Quaternion().setFromEuler(new THREE.Euler(x,y,z));
    },

    2. 创建关键帧轨道

    关键帧轨道(KeyframeTrack)是关键帧(keyframes)的定时序列, 它由时间和相关值的列表组成, 用来让一个对象的某个特定属性动起来。这里预设好一些轨道,以便于我们是使用

    let temp = new THREE.Mesh(new THREE.BoxGeometry(1), new THREE.MeshBasicMaterial());
    let leg_l_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q2.x,q2.y,q2.z,q2.w,q1.x,q1.y,q1.z,q1.w,q2.x,q2.y,q2.z,q2.w]);
    let leg_r_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q1.x,q1.y,q1.z,q1.w,q2.x,q2.y,q2.z,q2.w,q1.x,q1.y,q1.z,q1.w]);
    let leg_l_b = new THREE.KeyframeTrack('temp.quaternion', [0,1.2,2,3.2,4], [q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w]);
    let leg_r_b = new THREE.KeyframeTrack('temp.quaternion', [0,1.2,2,3.2,4], [q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w,q3.x,q3.y,q3.z,q3.w,q4.x,q4.y,q4.z,q4.w]);
    let arm_l_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q1.x,q1.y,q1.z,q1.w,q5.x,q5.y,q5.z,q5.w,q1.x,q1.y,q1.z,q1.w]);
    let arm_r_t = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q5.x,q5.y,q5.z,q5.w,q1.x,q1.y,q1.z,q1.w,q5.x,q5.y,q5.z,q5.w]);
    let arm_l_b = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q4.x,q4.y,q4.z,q4.w,q6.x,q6.y,q6.z,q6.w,q4.x,q4.y,q4.z,q4.w]);
    let arm_r_b = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q6.x,q6.y,q6.z,q6.w,q4.x,q4.y,q4.z,q4.w,q6.x,q6.y,q6.z,q6.w]);
    let head = new THREE.KeyframeTrack('temp.quaternion', [0,1,2,3,4], [q7.x,q7.y,q7.z,q7.w,q8.x,q8.y,q8.z,q8.w,q9.x,q9.y,q9.z,q9.w,q8.x,q8.y,q8.z,q8.w,q7.x,q7.y,q7.z,q7.w]);
    let body = new THREE.KeyframeTrack('temp.quaternion', [0,2,4], [q10.x,q10.y,q10.z,q10.w,q11.x,q11.y,q11.z,q11.w,q10.x,q10.y,q10.z,q10.w]);

    3. 创建动画剪辑

    动画剪辑(AnimationClip)是一个可重用的关键帧轨道集。这里为上面的关键帧轨道创建动画剪辑,并且剪辑的持续时间都是4秒

    let duration = 4;
    let clip_leg_l_t = new THREE.AnimationClip("default", duration, [leg_l_t]);
    let clip_leg_r_t = new THREE.AnimationClip("default", duration, [leg_r_t]);
    let clip_leg_l_b = new THREE.AnimationClip("default", duration, [leg_l_b]);
    let clip_leg_r_b = new THREE.AnimationClip("default", duration, [leg_r_b]);
    let clip_arm_l_t = new THREE.AnimationClip("default", duration, [arm_l_t]);
    let clip_arm_r_t = new THREE.AnimationClip("default", duration, [arm_r_t]);
    let clip_arm_l_b = new THREE.AnimationClip("default", duration, [arm_l_b]);
    let clip_arm_r_b = new THREE.AnimationClip("default", duration, [arm_r_b]);
    let clip_head = new THREE.AnimationClip("default", duration, [head]);
    let clip_body = new THREE.AnimationClip("default", duration, [body]);

    4. 创建动画混合器

    动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。

    mixer[0] = new THREE.AnimationMixer(bone4);
    mixer[1] = new THREE.AnimationMixer(bone5);
    mixer[2] = new THREE.AnimationMixer(bone6);
    mixer[3] = new THREE.AnimationMixer(bone7);
    mixer[4] = new THREE.AnimationMixer(bone10);
    mixer[5] = new THREE.AnimationMixer(bone11);
    mixer[6] = new THREE.AnimationMixer(bone12);
    mixer[7] = new THREE.AnimationMixer(bone13);
    mixer[8] = new THREE.AnimationMixer(bone2);
    mixer[9] = new THREE.AnimationMixer(bone3);

    5. 创建动画控制器

    它可以控制动画的播放、停止等功能

    action[0] = mixer[0].clipAction(clip_leg_l_t);
    action[1] = mixer[1].clipAction(clip_leg_r_t);
    action[2] = mixer[2].clipAction(clip_leg_l_b);
    action[3] = mixer[3].clipAction(clip_leg_r_b);
    action[4] = mixer[4].clipAction(clip_arm_l_t);
    action[5] = mixer[5].clipAction(clip_arm_r_t);
    action[6] = mixer[6].clipAction(clip_arm_l_b);
    action[7] = mixer[7].clipAction(clip_arm_r_b);
    action[8] = mixer[8].clipAction(clip_head);
    action[9] = mixer[9].clipAction(clip_body);

    在需要播放动画的时候调用action[n].play()即可播放动画了,你看他跑的多high啊,是不是很简单。
    最近文章有点难写,欢迎three.js的萌新提问,我会在下一期试着给出答案哦,如果没有,我就会在接下来的一段时间说一说three.js着色器材质,我相信这是一个十分有意思和具有挑战性的知识。

    转载请注明地址:郭先生的博客

  • 相关阅读:
    格式化数字,将字符串格式的数字,如:1000000 改为 1 000 000 这种展示方式
    jquery图片裁剪插件
    前端开发采坑之安卓和ios的兼容问题
    页面消息提示,上下滚动
    可以使用css的方式让input不能输入文字吗?
    智慧农村“三网合一”云平台测绘 大数据 农业 信息平台 应急
    三维虚拟城市平台测绘 大数据 规划 三维 信息平台 智慧城市
    农业大数据“一张图”平台测绘 大数据 房产 国土 农业 信息平台
    应急管理管理局安全生产预警平台应急管理系统不动产登记 测绘 大数据 规划 科教 三维 信息平台
    地下综合管廊管理平台测绘 大数据 地下管线 三维 信息平台
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13413819.html
Copyright © 2011-2022 走看看