【问题标题】:Three.js skeletal animations not working unless source is modified除非修改源,否则 Three.js 骨骼动画不起作用
【发布时间】:2014-12-21 15:15:22
【问题描述】:

使用 Three.js r68+ 我需要稍微修改源代码才能让我的动画正常工作。未经修改的每种类型的模型只有一个被动画化(每种类型的模型有多个生成)。

这是第 29407 行的修改后的源代码(发布的代码从 29389 开始):

THREE.AnimationHandler = {

LINEAR: 0,
CATMULLROM: 1,
CATMULLROM_FORWARD: 2,

//

add: function () { console.warn( 'THREE.AnimationHandler.add() has been deprecated.' ); },
get: function () { console.warn( 'THREE.AnimationHandler.get() has been deprecated.' ); },
remove: function () { console.warn( 'THREE.AnimationHandler.remove() has been deprecated.' ); },

//

animations: [],

init: function ( data ) {

    // original -> if ( data.initialized === true ) return;
    if ( data.initialized === true ) return data; //<-- modified

如果已初始化,该函数现在返回动画数据。我假设它不会因为缓存而这样做。我的问题是动画具有相同动画名称的多个模型的最佳实践是什么?我尝试根据模型名称对它们进行唯一命名,即:“Death_MaleWarrior”,但这没有效果。

目前我的模型和动画是这样处理的:

var modelArray = [];
var geoCache   = [];
var loader     = new THREE.JSONLoader(true);

var _MODEL = function(data){

  this.data       = data;  
  this.mesh       = null;
  this.animations = {};
  this.canAnimate = false;

  this.parseAnimations = function () {

    var len,i,anim;

    if (this.mesh) {

          if( this.mesh.geometry.animations ){
              this.canAnimate = true;
              len = this.mesh.geometry.animations.length;
              if( len ){
                  for(i=0;i<len;i++){
                      anim = this.mesh.geometry.animations[i];
                      if( anim ){
                        this.animations[anim.name] = new THREE.Animation( this.mesh, anim );
                      }
                  }
              }
          }
      }
  };

  this.playAnimation = function(label){

    if (this.canAnimate) {
      if( this.animations[label] ){
        //if( this.animations[label].data ){
          this.animations[label].play(0,1);
        //}
      }
    }
    return false;

  };

  this.load = function(geo){

    var mat;

    mat = new THREE.MeshPhongMaterial({color:somecolor, skinning:true})

    this.mesh = new THREE.SkinnedMesh(geo,mat);

    this.mesh.position.x = this.data.position[0];
    this.mesh.position.y = this.data.position[1];
    this.mesh.position.z = this.data.position[2];

    this.parseAnimations();

    scene.add(this.mesh);

    this.playAnimation('Idle');

  };

  this.init = function(){

    var geo;

    if( geoCache[this.data.name] ){
      geo = geoCache[this.data.name];
      this.load(geo); 
    }else{
       geo = loader.parse(JSON.parse(this.data.json)).geometry;
       geoCache[this.data.name] = geo;
       this.load(geo);            
    }        

  };

  this.init();

};

var dataArray = [{name:'MaleWarrior',json:'json_data',position:[x,y,z]},{name:'FemaleWarrior',json:'json_data',position:[x,y,z]},{name:'MaleWarrior',json:'json_data',position:[x,y,z]}];

for(var i=0, len=objectArray.length; i<len; i++){
  modelArray.push(new _MODEL(dataArray[i]) );
}

在此示例中,第一个 MaleWarrior 将设置动画,但第二个则不会。如果有第二个女性,她也不会被动画化,因为动画(即使它是一个新的 THREE.Animation() )将被视为已初始化并且不会返回任何数据。如果我不检查 playAnimation 中是否存在 animations.data,我会在第 29665 行收到错误““Uncaught TypeError: Cannot read property 'name' of undefined”。

我正在做什么绕过动画缓存并损害性能?我觉得我错过了什么。没有数据的动画怎么播放?

每个模型“空闲”、“运行”、“攻击”等的所有动画名称都相同。

任何帮助将不胜感激。如果我不够清楚,请告诉我。我添加了更多细节。

【问题讨论】:

  • 没有必要修改代码。如果您使用 JSON 加载器,也许您应该检查导出模型的方式?此外,对于您创建的每个 THREE.SkinnedMesh 以及您希望为其播放动画,您必须创建一个 THREE.Animation 对象,并调用其 .play 方法。也许您认为您只需为所有 THREE.SkinnedMesh 创建一个 THREE.Animation?很可能您必须检查您的 JSON 及其加载,因为 geometry.animations 可能没有加载。否则,我认为您的代码没有理由不工作。也许还有那个 Animationhandler 修改的行。
  • 另外,通常定义了animation.data。它在您调用 THREE.Animation 构造函数时设置。如果您发布指向其余代码和正在加载的 JSON 文件的链接,我们可以为您提供更多帮助。
  • 每个蒙皮网格都有自己的 THREE.Animation 对象数组。为每个单独的网格运行 parseAnimations 函数。 AnimationHandler (pre r68) 行被注释掉。 JSONLoader 没有问题。 r68 之前一切正常。
  • 另外,您正在该代码中创建一个名为“animation”的全局,因为您忘记使用“var”指定本地范围,应该是“var animation = new THREE.Animation...” .
  • 我相信你有一个更大的对象,它具有那些 .animations 和 .mesh 属性,看到这一点会很有用,因为你的问题可能存在,而不是在你引用的这段代码中在这里。

标签: animation three.js


【解决方案1】:

这原来是一个官方的three.js错误。

https://github.com/mrdoob/three.js/issues/5516

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 1970-01-01
    • 2013-11-03
    • 2013-12-24
    • 2016-09-13
    • 2013-09-22
    • 2021-08-03
    • 2023-03-23
    • 2014-12-15
    相关资源
    最近更新 更多