首页 文章

Three.js - 蒙皮骨架网格实例,动画和混合

提问于
浏览
25

我正在开发一款小型多人游戏,它有一个单一的皮肤玩家网格,很多玩家使用它 . 一些背景:我've tried loading via maya and blender collada export. Both seem to reference some form of animation data but I couldn' t让它工作 . 我已经尝试过maya JSON导出器,它只用一条物质线吐出很小的1k文件 . 最后,搅拌机JSON导出器工作 . 对于那些也试图加载蒙皮网格的人,我发现这非常有帮助:Model with bones animation (blender export) animating incorrectly in three.js

所以现在我有一个 geometry 对象和一个来自JSON加载器的 materials 数组 .

我可以在材质上设置 skinning=true ,创建 THREE.SkinnedMesh ,将其添加到场景中,通过 THREE.AnimationHandler.addI'm quite unclear on what the AnimationHandler actually does )添加动画,创建 THREE.Animation ,调用 play()update(dt) . 最后我在我的场景中播放了一个网格和一个动画 .

现在我想要的是这些......

  • Many instances - 我希望在我的场景中运行多个玩家模型 .

  • 我不希望多次加载相同的网格和动画数据 .

  • 动画时间应该是每个实例(因此它们不能同步动画) .

我应该为同一型号创建多个 THREE.SkinnedMeshTHREE.Animation 吗? THREE.AnimationHandler 在哪里进来?

  • Many animations - 我希望能够单独播放空闲/运行周期 .

AFAIK只有一个动画关键帧的时间轴 . Three.js如何为我分区,或者我必须手动执行此操作?

  • Animation Blending - 当角色停止运行并且使用空闲动画静止不动时,我不想暂停运行动画并将该状态重新混合到空闲动画中 .

目前这是否可以使用蒙皮网格(不是变形目标)?是否有关于此的示例或文档?

任何信息都会受到高度赞赏,即使只是朝着正确的方向努力 . 我不是在完整的教程之后,我想了解一些关于这些功能的更高级别的信息 .

我可以愉快地实现2和3,但我想要一些关于threejs皮肤和动画框架的信息/描述文档来帮助我入门 . 例如,this并不多 .

[编辑]
谢谢,@ NishchitDhanani,这个页面相当不错,但没有提到多个动画或混合骨骼动画:http://chimera.labs.oreilly.com/books/1234000000802/ch05.html#animating_characters_with_skinning

这个页面说多个动画仍然是当前的问题但不多(在评论中稍微讨论过):http://devmatrix.wordpress.com/2013/02/27/creating-skeletal-animation-in-blender-and-exporting-it-to-three-js/

目前的答案是......

  • 使用了很多 THREE.SkinnedMesh 但仍然不确定 THREE.AnimationHandler .

  • Don 't know. Perhaps there'是一种在 THREE.Animation 中手动修改开始/结束关键帧的方法 .

  • 未实施AFAIK . 我可能会尝试创建一个自定义着色器,可以使用两个 THREE.Animation 并在它们之间进行插值 .

3 回答

  • 0

    从版本67(2014年4月)开始,支持骨架动画混合和多个动画 . 您仍然需要为每个模型创建 SkinnedMesh . AnimationHandler 负责每帧更新(勾选)动画,因此您应该在其上调用更新而不是在每个 Animation 上手动调用 .

    请参阅新添加的示例: webgl_animation_skinning_blending.html 或在此处查看我自己的几个:

    Basic Character Controller (with time warped speed blend)

    Time Warped Speed Blend

  • 0

    我已经能够同时部署使用Blender创建的四个不同的动画模型并导出为JSON文件,方法是使用JSON加载器使用单独定制的函数为每个模型创建单独的蒙皮网格 . 我的四个模型中的每一个都有不同的网格,动画,纹理和关键帧数量 .

    var loader = new THREE.JSONLoader(); 
    loader.load("model_1.js", createSkinnedMeshforModel_1);
    loader.load("model_2.js", createSkinnedMeshforModel_2);
    loader.load("model_3.js", createSkinnedMeshforModel_3);
    
    ...
    
    var animations = [];
    
    function createSkinnedMeshforModel_1( geometry, materials )
    {
      var myModel1, animation;
      THREE.AnimationHandler.add( geometry.animation );
      myModel1 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
      enableSkinning( myModel1 );
      scene.add( myModel1 );
      animation = new THREE.Animation(myModel1, Model1_Animation_title, THREE.AnimationHandler.CATMULLROM);
      animations.push( animation );
      for( var i = 0; i < animations.length; i ++ )
      {
        animations[ i ].play();
      }
    }
    
    
    function createSkinnedMeshforModel_2( geometry, materials )
    {
      var myModel2, animation;
      THREE.AnimationHandler.add( geometry.animation );
      myModel2 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
      enableSkinning( myModel2 );
      scene.add( myModel2 );
      animation = new THREE.Animation(myModel2, Model2_Animation_title, THREE.AnimationHandler.CATMULLROM);
      animations.push( animation );
      for( var i = 0; i < animations.length; i ++ )
      {
        animations[ i ].play();
      }
    }
    
    function createSkinnedMeshforModel_3( geometry, materials )
    {
      var myModel3, animation;
      THREE.AnimationHandler.add( geometry.animation );
      myModel3 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
      enableSkinning( myModel3 );
      scene.add( myModel3 );
      animation = new THREE.Animation(myModel3, Model3_Animation_title, THREE.AnimationHandler.CATMULLROM);
      animations.push( animation );
      for( var i = 0; i < animations.length; i ++ )
      {
        animations[ i ].play();
      }
    }
    

    enableSkinning()函数与DEVMATRIX's really helpful tutorial中提供的函数相同

    “Modelx_Animation_title”变量是Blender中定义的动画 Headers 名称,并由Three.js Blender导出器复制到模型的导出JSON文件中 .

    当我加载给定模型的多个副本时,它们最初在同步中进行动画制作 . 但是,我可以通过在再次开始播放之前单独暂停每个模型一段短暂的持续时间来让它们动画不同步 . 每个模型的动画从它们暂停的帧恢复 .

    animations[ i ].pause();
    ... (random delay) ...
    animations[ i ].play();
    

    也许这种方法提供了问题1的解决方案,并可能提出问题2 .

    关于问题2,Three.js发布r62更新了Blender导出器以允许“导出多个操作” . 虽然我没有尝试过,但这可能允许加载给定模型的两个或更多副本,同时为不同的动作指定动画 Headers . 然后,当需要不同的操作时,可以将模型交换进出视图 .

    如果说工作,然后问题3的可能解决方案可能是在Blender中创建一个额外的动画动作,将模型从活动状态混合到它的空闲状态 .

  • 12

    @Xealgo:Maya有一个新的出口商,也可以做骨骼和动画 . 在我被迫使用Blender工作流程之前,几个月前我很想拥有它 . :)

    这是一个链接:https://github.com/mrdoob/three.js/tree/dev/utils/exporters/maya

相关问题