将三个.JS骨骼动画更新为基于新混音器的系统



r73中引入了混音器系统,从那时起,我一直在尝试将游戏更新为这个新系统。

我几乎在那里,除了一件事。与某些几何形状的某些动画进行交叉坠落有略有延迟,而R72中不存在。我黑客入侵了R72的搅拌机和动画功能以允许回调,并且效果很好。在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中已删除的行为?

这是三个中的错误。

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

关闭。

最新更新