From c10cfa7c33c4f7fcb820f6aebd6bcc3be6ed9823 Mon Sep 17 00:00:00 2001 From: yinsx Date: Tue, 3 Feb 2026 14:16:42 +0800 Subject: [PATCH] 1 --- .gitignore | 3 +- examples/3d/babylonAdapter.js | 76 --- examples/3d/blendshapeAnimator.js | 67 --- examples/3d/index.html | 110 ++-- examples/3d/main.js | 494 ++++++++++++++++-- examples/3d/styles.css | 81 ++- services/a2f_api/.gitignore | 6 + .../__pycache__/a2f_service.cpython-311.pyc | Bin 3338 -> 3339 bytes ...ext_to_blendshapes_service.cpython-311.pyc | Bin 19673 -> 19674 bytes services/a2f_api/a2f_service.py | 4 +- .../a2f_api/text_to_blendshapes_service.py | 2 +- 工作日报_2025-12-25.md | 43 -- 12 files changed, 603 insertions(+), 283 deletions(-) create mode 100644 services/a2f_api/.gitignore delete mode 100644 工作日报_2025-12-25.md diff --git a/.gitignore b/.gitignore index 146c9fa..a6d5a5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ data/ a2f_venv/ external/ -nul \ No newline at end of file +nul +examples \ No newline at end of file diff --git a/examples/3d/babylonAdapter.js b/examples/3d/babylonAdapter.js index b2bf58a..86b9b5e 100644 --- a/examples/3d/babylonAdapter.js +++ b/examples/3d/babylonAdapter.js @@ -31,82 +31,6 @@ class BabylonMorphTargetAdapter { return totalTargets; } - async warmupInvisible(scene) { - console.log('开始预热...'); - const startTime = performance.now(); - - const allTargets = Object.values(this.morphTargetCache).flat(); - const totalTargets = allTargets.length; - console.log(`预热 ${totalTargets} 个 morph targets`); - - // 多轮预热,用不同值组合 - const rounds = 10; - for (let r = 0; r < rounds; r++) { - const val = (r % 2 === 0) ? 1.0 : 0; - allTargets.forEach(mt => mt.influence = val); - scene.render(); - await new Promise(r => requestAnimationFrame(r)); - } - - // 重置 - allTargets.forEach(mt => mt.influence = 0); - scene.render(); - - // 等待几帧让 GPU 完全稳定 - for (let i = 0; i < 5; i++) { - await new Promise(r => requestAnimationFrame(r)); - } - - console.log(`预热完成,耗时 ${(performance.now() - startTime).toFixed(2)}ms`); - } - - warmupShaders(scene) { - console.log('开始shader预热...'); - const startTime = performance.now(); - - // 强制同步更新所有 morph target managers - this.meshes?.forEach(mesh => { - const mtm = mesh.morphTargetManager; - if (mtm) { - mtm.enableNormalMorphing = true; - mtm.enableTangentMorphing = true; - } - }); - - // 预热:强制触发着色器编译 - // 使用多种值组合来触发所有可能的shader变体 - const testValues = [0, 0.2, 0.4, 0.6, 0.8, 1.0]; - - for (let pass = 0; pass < testValues.length; pass++) { - const value = testValues[pass]; - for (const targets of Object.values(this.morphTargetCache)) { - targets.forEach(mt => { - mt.influence = value; - }); - } - - // 每次设置后都渲染,确保shader编译 - if (scene) { - scene.render(); - } - } - - // 重置所有影响值 - for (const targets of Object.values(this.morphTargetCache)) { - targets.forEach(mt => { - mt.influence = 0; - }); - } - - // 最后渲染一次确保重置生效 - if (scene) { - scene.render(); - } - - const elapsed = performance.now() - startTime; - console.log(`shader预热完成,耗时 ${elapsed.toFixed(2)}ms`); - } - setInfluence(name, value) { const lowerName = name.toLowerCase(); const targets = this.morphTargetCache[lowerName]; diff --git a/examples/3d/blendshapeAnimator.js b/examples/3d/blendshapeAnimator.js index 05e2e75..d534cda 100644 --- a/examples/3d/blendshapeAnimator.js +++ b/examples/3d/blendshapeAnimator.js @@ -24,11 +24,7 @@ class BlendShapeAnimator { this.deltaThreshold = typeof config.deltaThreshold === 'number' ? config.deltaThreshold : 0.002; // Skip re-applying nearly identical values - this.prewarmFrameCount = typeof config.prewarmFrameCount === 'number' - ? config.prewarmFrameCount - : 30; this.lastFrameBlendShapes = {}; - this._hasPrewarmed = false; // 空闲动画参数 this.blinkParams = config.blinkParams || { @@ -97,7 +93,6 @@ class BlendShapeAnimator { this.animationFrames = frames || []; this.animationShapeNames = this._collectAnimationShapeNames(this.animationFrames); this.lastFrameBlendShapes = {}; - // 不重置 _hasPrewarmed,因为全局预热只需要做一次 } appendAnimationFrames(frames) { @@ -107,7 +102,6 @@ class BlendShapeAnimator { this.animationFrames.push(...frames); const newNames = this._collectAnimationShapeNames(frames); - // 不重置 _hasPrewarmed if (newNames.length === 0) { return; @@ -227,49 +221,6 @@ class BlendShapeAnimator { this.lastFrameBlendShapes = {}; } - _prewarmAnimation() { - // 同步预热已移除,改用异步预热 - this._hasPrewarmed = true; - } - - // 异步分帧预热 - 预热所有 morph targets,确保 GPU 真正渲染 - async prewarmAsync(scene) { - if (!this.morphTargetAdapter) { - return; - } - - // 获取所有可用的 morph targets,而不只是当前动画用到的 - const allShapes = this.morphTargetAdapter.morphTargetCache - ? Object.keys(this.morphTargetAdapter.morphTargetCache) - : this.animationShapeNames; - - const shapes = allShapes.filter( - name => !this.disabledShapesInAnimation.includes(name.toLowerCase()) - ); - - if (shapes.length === 0) return; - - console.log(`异步预热 ${shapes.length} 个 morph targets...`); - - // 用不同的值组合预热,触发所有可能的 shader 变体 - const testValues = [0.2, 0.5, 0.8, 1.0]; - for (const val of testValues) { - shapes.forEach(name => this.morphTargetAdapter.setInfluence(name, val)); - if (scene) scene.render(); - await new Promise(r => requestAnimationFrame(r)); - } - - // 重置并等待几帧确保稳定 - shapes.forEach(name => this.morphTargetAdapter.setInfluence(name, 0)); - for (let i = 0; i < 5; i++) { - if (scene) scene.render(); - await new Promise(r => requestAnimationFrame(r)); - } - - this._hasPrewarmed = true; - console.log('异步预热完成'); - } - _primeFirstFrame() { if (!this.morphTargetAdapter || this.animationFrames.length === 0) { return; @@ -297,24 +248,6 @@ class BlendShapeAnimator { } } - _touchAnimationShapes() { - if (!this.morphTargetAdapter || !Array.isArray(this.animationShapeNames) || this.animationShapeNames.length === 0) { - return; - } - - const touchValue = Math.max(this.minBlendShapeValue * 1.2, 0.05); - const touched = []; - - this.animationShapeNames.forEach(name => { - this.morphTargetAdapter.setInfluence(name, touchValue); - touched.push(name); - }); - - touched.forEach(name => { - this.morphTargetAdapter.setInfluence(name, 0); - }); - } - _scheduleAnimationStart() { // 只设置开始时间,动画由统一的 RAF 循环驱动 this.animationStartTime = performance.now(); diff --git a/examples/3d/index.html b/examples/3d/index.html index b127791..b28f866 100644 --- a/examples/3d/index.html +++ b/examples/3d/index.html @@ -17,54 +17,62 @@ -
-

数字人形态键控制

- -
- - +
+
+

数字人形态键控制

+
-
- - +
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
+ + +
+ + + + + + + +
+ + + + +
+
+ +
- -
- -
- -
- - -
- -
- - -
- -
- - -
- - - - - - - -
@@ -72,11 +80,15 @@
-
-

空闲动画控制

+
+
+

空闲动画控制

+ +
- -
+
+ +