2016-06-26 35 views
10

混音器系統在r73中引入,從那時起我一直在嘗試將我的遊戲更新到這個新系統。更新Three.js骨骼動畫到新的基於混音器的系統

除了一件事我幾乎沒有。對某些幾何圖形的某些動畫進行交叉淡入淡出略有延遲,這在r72中並不存在。我入侵了r72的BlendCharacter和Animation函數以允許回調,並且效果很好。在73中,通過事件觸發器內置了這個功能,這並不是必需的。

在下面的小提琴中,一切都按預期工作(r72)。

http://jsfiddle.net/titansoftime/a93w5hw0/

<script src="http://www.titansoftime.com/webgl/Three72.full.js"></script> 
<script src="http://www.titansoftime.com/webgl/BlendCharacter2.js"></script> 
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/DDSLoader.js"></script> 

var scene, camera, renderer, ambient, directional; 
var mesh, geoCache={}; 
var clock, jsLoader, ddsLoader; 

init(); 
animate(); 

function init() { 

     scene = new THREE.Scene(); 

     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000); 
     camera.position.z = 20; 
     camera.position.y = 10; 

     ambient = new THREE.AmbientLight(0xffffff);  
     scene.add(ambient); 

     directional = new THREE.DirectionalLight(0xffffff,1); 
     directional.position.set(1,1,0); 
     scene.add(directional); 

     clock = new THREE.Clock(); 

     jsLoader = new THREE.JSONLoader(true);  
     ddsLoader = new THREE.DDSLoader(); 

     renderer = new THREE.WebGLRenderer({antialias:true}); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     renderer.setClearColor(0xffffff, 1); 

     document.getElementById('idle').onclick = function(e){ 
      play('Idle',true); 
     }; 

     document.getElementById('run').onclick = function(e){ 
      play('Run',true); 
     }; 

     document.getElementById('melee').onclick = function(e){ 
      play('MelleAttack'); 
     }; 

     document.getElementById('magic').onclick = function(e){ 
      play('MagicAttack'); 
     };  

     document.body.appendChild(renderer.domElement); 

     loadFloor(); 

     loadModel(); 

} 

function createModel(json){ 

     var geo, geo2; 

     if(geoCache[json.name]){ 

       geo = geoCache[json.name]; 

     }else{ 

       geo2 = jsLoader.parse(json).geometry; 

       var m = new THREE.SkinnedMesh(geo2); 
       m.normalizeSkinWeights(); 
       geo2 = m.geometry; 

       geo = new THREE.BufferGeometry().fromGeometry(geo2); 
       geo.bones = geo2.bones; 
       geo.animations = geo2.animations; 

       geoCache[json.name] = geo; 

     } 

     var tex = ddsLoader.load('http://www.titansoftime.com/utils.php?task=getTexture&id=16'); 

     var mat = new THREE.MeshPhongMaterial({map:tex,skinning:true,side:THREE.DoubleSide}); 

     mesh = new THREE.BlendCharacter(); 
     mesh.load(geo,mat); 

     //mesh.scale.set(10,10,10); 

     //mesh.mixer = new THREE.AnimationMixer(mesh); 

     //parseAnimations();  

     scene.add(mesh); 

     play('Idle',true); 

     camera.lookAt(new THREE.Vector3(mesh.position.x,7,mesh.position.z)); 

} 

function loadModel(){ 

     $.ajax({ 

       url: 'http://www.titansoftime.com/utils.php', 
       data: 'task=getModel&id=16', 
       crossDomain: true, 
       type: 'POST', 
       success: function(response){ 
         createModel(JSON.parse(response)); 
       } 

     });  

} 

function loadFloor(){ 

     var geo = new THREE.PlaneBufferGeometry(50,50); 

     geo.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI/2)); 

     var mat = new THREE.MeshBasicMaterial({color:0x0000ff}); 

     var mesh = new THREE.Mesh(geo,mat); 

     scene.add(mesh); 

} 

function play(name,loop){ 

    loop = loop || false; 

    var anim = mesh.animations[name]; 

    anim.loop = loop; 

    if(mesh.currentAnimation){ 

     var cur = mesh.animations[mesh.currentAnimation]; 

     var theTime = 0.175;     

     if(!cur.loop){ 

      var diff = cur.data.length - cur.currentTime; 

      theTime = Math.max(0,Math.min(theTime,diff)); 

     } 

     console.log('blending: '+name); 
     mesh.crossfade(name,theTime,function(){ 

      play('Idle',true) 

     }); 

    }else{    
     console.log('playing: '+name); 
     mesh.play(name,loop); 
    } 

} 

function animate() { 

     requestAnimationFrame(animate); 

     var delta = clock.getDelta(); 

     if(mesh){ 

       mesh.update(delta); 

     } 

     THREE.AnimationHandler.update(delta); 

     renderer.render(scene, camera); 

} 

這一個(R78)的作品,除了一個動畫(魔法攻擊)的返回空閒動畫前一個小,但明顯的延遲幾乎罰款。在其他模型中,它是近戰動畫,有些則完全沒有問題。超級困惑,因爲他們都在72

http://jsfiddle.net/titansoftime/2sh95etj/

<script src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script> 
<script src="https://rawgit.com/mrdoob/three.js/master/examples/js/loaders/DDSLoader.js"></script> 

var scene, camera, renderer, ambient, directional; 
var mesh, geoCache={}; 
var clock, jsLoader, ddsLoader; 

init(); 
animate(); 

function init() { 

     scene = new THREE.Scene(); 

     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000); 
     camera.position.z = 20; 
     camera.position.y = 10; 

     ambient = new THREE.AmbientLight(0xffffff);  
     scene.add(ambient); 

     directional = new THREE.DirectionalLight(0xffffff,1); 
     directional.position.set(1,1,0); 
     scene.add(directional); 

     clock = new THREE.Clock(); 

     jsLoader = new THREE.JSONLoader(true);  
     ddsLoader = new THREE.DDSLoader(); 

     renderer = new THREE.WebGLRenderer({antialias:true}); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     renderer.setClearColor(0xffffff, 1); 

     document.getElementById('idle').onclick = function(e){ 
      play('Idle',true); 
     }; 

     document.getElementById('run').onclick = function(e){ 
      play('Run',true); 
     }; 

     document.getElementById('melee').onclick = function(e){ 
      play('MelleAttack'); 
     }; 

     document.getElementById('magic').onclick = function(e){ 
      play('MagicAttack'); 
     };  

     document.body.appendChild(renderer.domElement); 

     loadFloor(); 

     loadModel(); 

} 

function createModel(json){ 

     var geo, geo2; 

     if(geoCache[json.name]){ 

       geo = geoCache[json.name]; 

     }else{ 

       geo2 = jsLoader.parse(json).geometry; 

       var m = new THREE.SkinnedMesh(geo2); 
       m.normalizeSkinWeights(); 
       geo2 = m.geometry; 

       geo = new THREE.BufferGeometry().fromGeometry(geo2); 
       geo.bones = geo2.bones; 
       geo.animations = geo2.animations; 

       geoCache[json.name] = geo; 

     } 

     var tex = ddsLoader.load('http://www.titansoftime.com/utils.php?task=getTexture&id=16'); 

     var mat = new THREE.MeshPhongMaterial({map:tex,skinning:true,side:THREE.DoubleSide}); 

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

     //mesh.scale.set(10,10,10); 

     mesh.mixer = new THREE.AnimationMixer(mesh); 

     parseAnimations(); 

     play('Idle',true); 

     scene.add(mesh); 

     camera.lookAt(new THREE.Vector3(mesh.position.x,7,mesh.position.z)); 

} 

function loadModel(){ 

     $.ajax({ 

       url: 'http://www.titansoftime.com/utils.php', 
       data: 'task=getModel&id=16', 
       crossDomain: true, 
       type: 'POST', 
       success: function(response){ 
         createModel(JSON.parse(response)); 
       } 

     });  

} 

function loadFloor(){ 

     var geo = new THREE.PlaneBufferGeometry(50,50); 

     geo.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI/2)); 

     var mat = new THREE.MeshBasicMaterial({color:0x0000ff}); 

     var mesh = new THREE.Mesh(geo,mat); 

     scene.add(mesh); 

} 

function play(name,loop){ 

    var to = mesh.animations[ name ];  

    if(mesh.currentAnimation){ 

     var from = mesh.animations[ mesh.currentAnimation ]; 

     to.reset(); 

     if(loop){ 

      to.setLoop(THREE.LoopRepeat); 
      to.clampWhenFinished = false; 

     }else{ 

      to.setLoop(THREE.LoopOnce, 0); 
      to.clampWhenFinished = true;      

      mesh.mixer.addEventListener('finished',function(e){ 

       play('Idle',true); 

      });      

     } 

     from.play(); 
     to.play(); 

     from.enabled = true; 
     to.enabled = true; 

     from.crossFadeTo(to, 0.3);      

    }else{ 

     to.play(); 

    } 

    mesh.currentAnimation = name; 

} 

function parseAnimations(){ 

    var o, anim, anims = {}; 

    console.log(mesh); 

    for(var i=0,len=mesh.geometry.animations.length;i<len;i++){ 

     o = mesh.geometry.animations[i]; 
     if(o){ 

      anim = mesh.mixer.clipAction(o,mesh); 
      anim.setEffectiveWeight(1); 

      anims[o.name] = anim; 

     } 

    } 

    mesh.animations = anims; 

} 

function animate() { 

     requestAnimationFrame(animate); 

     var delta = clock.getDelta(); 

     if(mesh){ 

      if(mesh.mixer){ 

       mesh.mixer.update(delta); 

      } 

     } 

     renderer.render(scene, camera); 

} 

正常工作,這究竟是爲什麼?

更新:我注意到這是問題不限於動畫之間的混合。我的一個動畫循環現在有一個延遲!

72:http://jsfiddle.net/titansoftime/8v0pasp5/

78:http://jsfiddle.net/titansoftime/n6apnj3z/

這是怎麼回事!?是否有某種自動糾正行爲或72行中已被刪除的行爲?

+0

您鏈接到的79dev小提琴不適合我。 JS「無法讀取屬性」錯誤,這似乎與JSONLoader.parse()有關。我也注意到你是JSON版本3,是不是有更新版本的three.js json格式? – 2pha

+0

他們肯定已經在最近推出了79dev的東西,我把它設置爲78.他們有一個更新的json規範是的,但是他們的出口商並沒有使用它(還)。在這種情況下,不要提及json文件的格式並不完全相關,json加載器是爲spec 3構建的。感謝您讓我知道dev中的中斷。 – Hobbes

+0

帆船的新提琴似乎對我很好用 – 2pha

回答