混音器系统是在r73中引入的,从那时起我一直在尝试将我的游戏更新到这个新系统。
我除了一件事外几乎没有。某些具有某些几何形状的动画的交叉渐变有一点延迟,这在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中的某些行已被删除?