2016-06-26 4 views
10

믹서 시스템이 r73에 도입되었습니다. 그 이후로이 새로운 시스템으로 게임을 업데이트하려고 노력해 왔습니다.Three.js 스켈 레탈 애니메이션을 새로운 믹서 기반 시스템으로 업데이트

나는 단 한가지를 제외하고는 거기서 아주입니다. 특정 지오메트리가있는 일부 애니메이션의 크로스 페이드는 r72에없는 약간의 지연이 있습니다. 콜백을 허용하기 위해 r72의 BlendCharacter 및 Animation 함수를 해킹했는데 잘 작동합니다. 73에서는이 기능이 이벤트 트리거를 통해 내장되어 있기 때문에 이것이 필요하지 않았습니다.

다음 바이올린에서는 모든 것이 의도 한대로 작동합니다 (r72).

<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)

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

한 애니메이션 (마법 공격력) 유휴 애니메이션에 반환하기 전에 작지만 눈에 띄는 지연이를 제외한 거의 잘 작동합니다. 다른 모델의 경우 Melee 애니메이션이고 일부에서는 전혀 문제가 없습니다. 슈퍼 혼란 그들은 모두 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 spec을 가지고 있지만, 수출업자는 아직 그것을 사용하지 않는다. json 파일의 형식이 완전히 관련이있는 것은 아니며, json 로더는 spec 3을 위해 만들어졌습니다. dev에있는 break에 대해 알려 주셔서 감사합니다. – Hobbes

+0

세일링 보트의 새로운 피들이 나를 위해 잘 작동하는 것 같습니다 – 2pha

답변