我正在尝试将使用three.js插件导出的Blender中的多层动画导入JavaScript,并通过麦克风频率输入触发不同的动画。我已经能够通过按钮和根据麦克风输入的频率旋转的.obj组合播放动画。但我很难将麦克风分配给动画。
<div class="info">
<button onclick="fadeAction( 'idle' );">idle</button>
<button onclick="fadeAction( 'run' );">run</button>
<button onclick="fadeAction( 'wrap' );">wrap</button>
</div>
loader.load( 'tentacleanimation6.json', function( geometry, materials ) {
materials.forEach( function ( material ) {
material.skinning = true;
} );
mesh = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial( materials )
);
mixer = new THREE.AnimationMixer( mesh );
action.idle = mixer.clipAction( geometry.animations[ 1 ] );
action.run = mixer.clipAction( geometry.animations[ 0 ] );
action.wrap = mixer.clipAction( geometry.animations[ 2 ] );
action.idle.setEffectiveWeight( 1 );
action.run.setEffectiveWeight( 1 );
action.wrap.setEffectiveWeight( 1 );
action.idle.play();
mesh.position.y = 0;
mesh.position.x = -3;
scene.add( mesh );
} );
fadeAction = function () {
var activeActionName = 'idle';
return function ( name ) {
var from = action[ activeActionName ].play();
var to = action[ name ].play();
from.enabled = true;
to.enabled = true;
from.crossFadeTo( to, .3 );
activeActionName = name;
}
}();
然后处理来自getUserMedia的麦克风输入,然后触发.obj文件旋转:
script_processor_analysis_node.onaudioprocess = function() {
analyser_node.getByteFrequencyData(array_freq_domain);
if (microphone_stream.playbackState == microphone_stream.PLAYING_STATE) {
var render = function () {
for ( var i = 0; i < (array_freq_domain.length); i++ ){
var valueone = array_freq_domain[array_freq_domain.length / 2];
mouthone.rotation.x = deg2rad( valueone ) / 7;
var valuetwo = array_freq_domain[6];
mouthtwo.rotation.x = deg2rad( valuetwo ) / 7;
}
renderer.render(scene, camera);
}
requestAnimationFrame( render );
}
}
问题变成两者结合在一起时我不确定在onaudioprocess部分需要调用什么来触发动画播放?渲染也似乎存在问题,因为onaudioprocess的函数需要像上面那样呈现,并且动画需要使用以下内容进行渲染,当它们组合时它们相互抵消:
;( function update () {
requestAnimationFrame( update );
var delta = clock.getDelta();
var theta = clock.getElapsedTime();
if ( mixer ) { mixer.update( delta ); }
renderer.render( scene, camera );
} )();