形态键预热
This commit is contained in:
@ -141,6 +141,29 @@ class BlendShapeAnimator {
|
||||
|
||||
// 注意:不停止眨眼,让眨眼继续运行
|
||||
|
||||
// 预演前10帧以避免首次播放卡顿
|
||||
console.log('预演前10帧...');
|
||||
const framesToPreview = Math.min(10, this.animationFrames.length);
|
||||
for (let i = 0; i < framesToPreview; i++) {
|
||||
const frame = this.animationFrames[i];
|
||||
const blendShapes = frame?.blendShapes || {};
|
||||
for (const key in blendShapes) {
|
||||
if (this.disabledShapesInAnimation.includes(key.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
this.morphTargetAdapter.setInfluence(key, blendShapes[key] * this.blendShapeScale);
|
||||
}
|
||||
}
|
||||
// 重置为0
|
||||
for (let i = 0; i < framesToPreview; i++) {
|
||||
const frame = this.animationFrames[i];
|
||||
const blendShapes = frame?.blendShapes || {};
|
||||
for (const key in blendShapes) {
|
||||
this.morphTargetAdapter.setInfluence(key, 0);
|
||||
}
|
||||
}
|
||||
console.log('预演完成');
|
||||
|
||||
this.stopAnimation(false);
|
||||
this.isPlaying = true;
|
||||
this.currentFrameIndex = 0;
|
||||
@ -149,6 +172,7 @@ class BlendShapeAnimator {
|
||||
this.streamingStallMs = 0;
|
||||
|
||||
this._animateFrame();
|
||||
|
||||
this.onStatusChange('info', '播放中...');
|
||||
}
|
||||
|
||||
@ -197,7 +221,8 @@ class BlendShapeAnimator {
|
||||
_animateFrame() {
|
||||
if (!this.isPlaying) return;
|
||||
|
||||
const now = performance.now();
|
||||
const frameStartTime = performance.now();
|
||||
const now = frameStartTime;
|
||||
if (this.streamingWaitStart !== null && this.animationFrames.length > this.currentFrameIndex + 1) {
|
||||
this.streamingStallMs += now - this.streamingWaitStart;
|
||||
this.streamingWaitStart = null;
|
||||
@ -242,8 +267,11 @@ class BlendShapeAnimator {
|
||||
? this.animationShapeNames
|
||||
: Object.keys(currentBlendShapes);
|
||||
|
||||
let updateCount = 0;
|
||||
const setInfluenceStart = performance.now();
|
||||
|
||||
for (const key of shapeNames) {
|
||||
// 跳过禁用列表中的 blendshape,让空闲动画继续控制它们
|
||||
// 跳过禁用列表中的 blendshape,让空闲动画继续控制它们
|
||||
if (this.disabledShapesInAnimation.includes(key.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
@ -254,10 +282,21 @@ class BlendShapeAnimator {
|
||||
const scaledValue = interpolatedValue * this.blendShapeScale;
|
||||
|
||||
this.morphTargetAdapter.setInfluence(key, scaledValue);
|
||||
updateCount++;
|
||||
}
|
||||
|
||||
const setInfluenceTime = performance.now() - setInfluenceStart;
|
||||
|
||||
this.currentFrameIndex = targetFrameIndex;
|
||||
|
||||
// 性能监控前100帧
|
||||
if (targetFrameIndex < 100) {
|
||||
const totalFrameTime = performance.now() - frameStartTime;
|
||||
if (totalFrameTime > 16.67) {
|
||||
console.warn(`帧${targetFrameIndex}耗时${totalFrameTime.toFixed(2)}ms (setInfluence: ${setInfluenceTime.toFixed(2)}ms, 调用${updateCount}次)`);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新当前句子显示
|
||||
const sentenceIndex = currentFrame?.sentenceIndex ?? -1;
|
||||
if (sentenceIndex !== this.currentSentenceIndex) {
|
||||
|
||||
Reference in New Issue
Block a user