混音器系統在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行中已被刪除的行爲?
您鏈接到的79dev小提琴不適合我。 JS「無法讀取屬性」錯誤,這似乎與JSONLoader.parse()有關。我也注意到你是JSON版本3,是不是有更新版本的three.js json格式? – 2pha
他們肯定已經在最近推出了79dev的東西,我把它設置爲78.他們有一個更新的json規範是的,但是他們的出口商並沒有使用它(還)。在這種情況下,不要提及json文件的格式並不完全相關,json加載器是爲spec 3構建的。感謝您讓我知道dev中的中斷。 – Hobbes
帆船的新提琴似乎對我很好用 – 2pha