Skip to content

Commit 53fdaf7

Browse files
author
shijiashuai
committed
feat: 集成 three-vrm 支持 + 借鉴 AIRI 项目模块化重构
- 安装 @pixiv/three-vrm 依赖 - 新增模块化 VRM hooks(借鉴 AIRI 架构): - useVRMLoader: 单例 GLTFLoader - useVRMEmote: lerp + easeInOutCubic 平滑表情过渡 - useVRMBlink: 正弦曲线自然眨眼 - useVRMLipSync: winner+runner 双通道口型混合 - useVRMEyeSaccades: 空闲眼球微动 - 新增 VRMAvatar 组件,完整映射 16 种动作到 VRM 骨骼 - Store 新增 avatarType/vrmModelUrl 状态 - DigitalHumanViewer 新增 AvatarSwitch 切换内置/VRM 角色 - 页面基础面板新增 VRM 模型加载 UI - 优化 CyberAvatar 外观:材质/比例/光环 - 新增项目配置:.gitattributes .npmrc .nvmrc .vscode/ - 新增 CLAUDE.md AGENTS.md .windsurfrules - 新增测试文件:store/engine/panels
1 parent 5f3606a commit 53fdaf7

31 files changed

Lines changed: 3214 additions & 327 deletions

.gitattributes

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# ========================
2+
# 换行符统一(LF)
3+
# ========================
4+
* text=auto eol=lf
5+
6+
# ========================
7+
# 前端源文件
8+
# ========================
9+
*.ts text eol=lf
10+
*.tsx text eol=lf
11+
*.js text eol=lf
12+
*.jsx text eol=lf
13+
*.json text eol=lf
14+
*.css text eol=lf
15+
*.html text eol=lf
16+
*.md text eol=lf
17+
*.yml text eol=lf
18+
*.yaml text eol=lf
19+
20+
# ========================
21+
# 配置文件
22+
# ========================
23+
*.editorconfig text eol=lf
24+
.gitignore text eol=lf
25+
.gitattributes text eol=lf
26+
.windsurfrules text eol=lf
27+
.env* text eol=lf
28+
29+
# ========================
30+
# Python 后端
31+
# ========================
32+
*.py text eol=lf
33+
*.txt text eol=lf
34+
requirements*.txt text eol=lf
35+
36+
# ========================
37+
# 二进制文件(禁止 diff / merge)
38+
# ========================
39+
*.png binary
40+
*.jpg binary
41+
*.jpeg binary
42+
*.gif binary
43+
*.ico binary
44+
*.webp binary
45+
*.svg text eol=lf
46+
*.woff binary
47+
*.woff2 binary
48+
*.ttf binary
49+
*.eot binary
50+
*.mp3 binary
51+
*.mp4 binary
52+
*.wav binary
53+
*.glb binary
54+
*.gltf text eol=lf
55+
56+
# ========================
57+
# 锁文件(不做 diff,减少冲突噪音)
58+
# ========================
59+
package-lock.json -diff linguist-generated=true
60+
pnpm-lock.yaml -diff linguist-generated=true
61+
yarn.lock -diff linguist-generated=true

.gitignore

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,97 @@
1-
# Logs
2-
logs
1+
# ========================
2+
# 依赖
3+
# ========================
4+
node_modules/
5+
.pnp/
6+
.pnp.js
7+
8+
# ========================
9+
# 构建产物
10+
# ========================
11+
dist/
12+
dist-ssr/
13+
build/
14+
*.tsbuildinfo
15+
16+
# ========================
17+
# 环境变量(敏感信息)
18+
# ========================
19+
.env
20+
.env.local
21+
.env.development.local
22+
.env.test.local
23+
.env.production.local
24+
*.local
25+
26+
# ========================
27+
# 测试 & 覆盖率
28+
# ========================
29+
coverage/
30+
*.lcov
31+
.nyc_output/
32+
33+
# ========================
34+
# 日志
35+
# ========================
36+
logs/
337
*.log
438
npm-debug.log*
539
yarn-debug.log*
640
yarn-error.log*
741
pnpm-debug.log*
842
lerna-debug.log*
943

10-
node_modules
11-
dist
12-
dist-ssr
13-
*.local
14-
15-
# Editor directories and files
44+
# ========================
45+
# 编辑器 & IDE
46+
# ========================
1647
.vscode/*
1748
!.vscode/extensions.json
18-
.idea
19-
.DS_Store
49+
!.vscode/settings.json
50+
.idea/
2051
*.suo
2152
*.ntvs*
2253
*.njsproj
2354
*.sln
2455
*.sw?
56+
*.code-workspace
57+
58+
# ========================
59+
# 操作系统
60+
# ========================
61+
.DS_Store
62+
Thumbs.db
63+
ehthumbs.db
64+
Desktop.ini
65+
*.lnk
2566

67+
# ========================
68+
# Python 后端
69+
# ========================
2670
__pycache__/
27-
*.pyc
71+
*.py[cod]
72+
*$py.class
73+
*.egg-info/
74+
.eggs/
75+
*.egg
76+
server/venv/
77+
server/.venv/
78+
server/.env
79+
80+
# ========================
81+
# 缓存
82+
# ========================
83+
.cache/
84+
.parcel-cache/
85+
.vite/
86+
*.tgz
87+
88+
# ========================
89+
# Vercel
90+
# ========================
91+
.vercel/
92+
93+
# ========================
94+
# AI 工具(本地配置)
95+
# ========================
96+
.trae/
97+
.kiro/

.npmrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# 强制检查 engines 字段中的 Node/npm 版本要求
2+
engine-strict=true
3+
4+
# 安装时使用精确版本号(避免 ^ 或 ~ 带来的隐式升级)
5+
save-exact=true
6+
7+
# Windows 兼容:设置脚本 shell
8+
script-shell=pwsh
9+
10+
# 减少安装噪音
11+
fund=false
12+
audit=false

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
18

.vscode/extensions.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"recommendations": [
3+
// TypeScript & React
4+
"ms-vscode.vscode-typescript-next",
5+
"dsznajder.es7-react-js-snippets",
6+
7+
// 样式
8+
"bradlc.vscode-tailwindcss",
9+
10+
// 代码质量
11+
"dbaeumer.vscode-eslint",
12+
"esbenp.prettier-vscode",
13+
"editorconfig.editorconfig",
14+
15+
// Git
16+
"eamodio.gitlens",
17+
"mhutchie.git-graph",
18+
19+
// 工具
20+
"christian-kohler.path-intellisense",
21+
"formulahendry.auto-rename-tag",
22+
"naumovs.color-highlight",
23+
24+
// 测试
25+
"vitest.explorer"
26+
]
27+
}

.vscode/settings.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
// 编辑器基础设置
3+
"editor.formatOnSave": true,
4+
"editor.defaultFormatter": "esbenp.prettier-vscode",
5+
"editor.tabSize": 2,
6+
"editor.insertSpaces": true,
7+
"editor.codeActionsOnSave": {
8+
"source.fixAll.eslint": "explicit",
9+
"source.organizeImports": "never"
10+
},
11+
12+
// 文件设置
13+
"files.eol": "\n",
14+
"files.encoding": "utf8",
15+
"files.trimTrailingWhitespace": true,
16+
"files.insertFinalNewline": true,
17+
"files.exclude": {
18+
"node_modules": true,
19+
"dist": true,
20+
".git": true,
21+
"coverage": true
22+
},
23+
24+
// TypeScript
25+
"typescript.preferences.importModuleSpecifier": "non-relative",
26+
"typescript.suggest.autoImports": true,
27+
"typescript.tsdk": "node_modules/typescript/lib",
28+
29+
// Tailwind CSS IntelliSense
30+
"tailwindCSS.includeLanguages": {
31+
"typescriptreact": "html"
32+
},
33+
"tailwindCSS.experimental.classRegex": [
34+
["cn\\(([^)]*)\\)", "'([^']*)'"],
35+
["cn\\(([^)]*)\\)", "\"([^\"]*)\""],
36+
["cn\\(([^)]*)\\)", "`([^`]*)`"]
37+
],
38+
39+
// ESLint
40+
"eslint.validate": [
41+
"javascript",
42+
"javascriptreact",
43+
"typescript",
44+
"typescriptreact"
45+
],
46+
47+
// 搜索排除
48+
"search.exclude": {
49+
"node_modules": true,
50+
"dist": true,
51+
"coverage": true,
52+
"package-lock.json": true
53+
},
54+
55+
// Emmet(JSX 支持)
56+
"emmet.includeLanguages": {
57+
"typescriptreact": "html"
58+
},
59+
60+
// 文件关联
61+
"files.associations": {
62+
"*.css": "tailwindcss"
63+
}
64+
}

.windsurfrules

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# MetaHuman 项目 Windsurf Rules
2+
3+
## 项目概述
4+
5+
MetaHuman 是基于 Web 的 3D 数字人交互平台,支持实时 3D 渲染、语音交互、表情控制和智能行为系统。全中文界面,深色/浅色双主题。
6+
7+
## 技术栈
8+
9+
- **前端**: React 18 + TypeScript 5 + Vite 5
10+
- **3D 渲染**: Three.js r158 + @react-three/fiber + @react-three/drei
11+
- **状态管理**: Zustand 4
12+
- **样式**: Tailwind CSS 3(`darkMode: "class"`,默认深色)
13+
- **图标**: Lucide React
14+
- **通知**: Sonner(`toast`)
15+
- **路由**: React Router DOM 6
16+
- **测试**: Vitest + @testing-library/react + fast-check
17+
- **部署**: Vercel
18+
19+
## 关键规则
20+
21+
### 1. 语言
22+
23+
- 所有回复使用中文
24+
- UI 界面文案为中文
25+
- 代码注释使用中文
26+
27+
### 2. 双主题样式(强制)
28+
29+
所有 UI 组件**必须**同时支持浅色和深色两套样式:
30+
- 浅色:直接写 class(如 `bg-white text-slate-800`)
31+
- 深色:使用 `dark:` 前缀(如 `dark:bg-slate-900 dark:text-white`)
32+
- **禁止**写只有深色或只有浅色的硬编码样式
33+
34+
### 3. 3D 渲染规范
35+
36+
- CyberAvatar 使用 `headGroupRef`(头部)和 `group`(身体)分离控制
37+
- 动画通过 `animState` ref + `THREE.MathUtils.lerp` 插值,**禁止直接设值**
38+
- 材质使用 `useMemo` 共享(`skinMat` / `armorMat` / `frameMat` / `glowCyan`)
39+
- `@react-three/fiber` 和 `@react-three/drei` 的类型声明警告**可忽略**,不影响编译运行
40+
41+
### 4. 状态管理规范
42+
43+
- 高频状态更新(如 FPS)使用 `debouncedSetState`(限制 10 次/秒)
44+
- UI 交互走正常 Zustand `set()`
45+
- 新增行为类型时,**必须同步更新**以下位置:
46+
- `digitalHumanStore.ts` → `BehaviorType` 联合类型
47+
- `DigitalHumanEngine.ts` → `VALID_BEHAVIORS` 数组
48+
- `DigitalHumanEngine.ts` → `ANIMATION_DURATIONS` 配置
49+
- `DigitalHumanEngine.ts` → 两处 `behaviorMap` 映射
50+
- `DigitalHumanEngine.ts` → 添加 `perform<Action>()` 组合方法
51+
52+
### 5. 新增动作的完整流程
53+
54+
需要修改 3 层文件:
55+
56+
1. **状态层**: `digitalHumanStore.ts` + `DigitalHumanEngine.ts`
57+
2. **渲染层**: `DigitalHumanViewer.enhanced.tsx` 的 `useFrame` 中添加头部/身体/手臂/光环/灯光动画分支
58+
3. **UI 层**: `BehaviorControlPanel.new.tsx` 添加按钮 + `AdvancedDigitalHumanPage.tsx` 添加键盘快捷键 + `KeyboardShortcutsHelp.tsx` 更新列表
59+
60+
### 6. 代码风格
61+
62+
- 路径别名:`@/*` → `./src/*`
63+
- 使用 `cn()` 工具函数合并 className(`@/lib/utils`)
64+
- 面板组件使用 3 列网格布局
65+
- 组合动作方法命名:`perform<ActionName>()`
66+
- 组件文件命名:`.new.tsx` = 中文化重构版,`.dark.tsx` = 深色主题版
67+
- 提交规范:Conventional Commits(`feat:` / `fix:` / `docs:` / `style:` / `refactor:`)
68+
69+
### 7. 测试规范
70+
71+
- 测试框架:Vitest + @testing-library/react
72+
- 测试环境:jsdom
73+
- 属性测试使用 fast-check(`__tests__/properties/`)
74+
- 运行命令:`npm run test:run`(单次)/ `npm run test`(watch)
75+
76+
### 8. 禁止事项
77+
78+
- 禁止删除或修改已有测试用例(除非明确要求)
79+
- 禁止在 3D 动画中直接设值(必须通过 lerp 插值)
80+
- 禁止创建只支持单一主题的 UI 组件
81+
- 禁止在组件内部重复创建 Three.js 材质(使用共享 useMemo 材质)
82+
- 禁止使用非 Lucide 的图标库
83+
84+
## 项目结构
85+
86+
```
87+
src/
88+
├── pages/ # 页面组件
89+
├── components/ # UI + 3D 组件
90+
├── core/
91+
│ ├── avatar/ # 数字人行为引擎
92+
│ ├── audio/ # TTS/ASR 语音服务
93+
│ ├── dialogue/ # 对话服务
94+
│ ├── vision/ # 视觉识别
95+
│ └── performance/ # 性能监控
96+
├── store/ # Zustand 状态管理
97+
├── hooks/ # 自定义 Hooks
98+
├── __tests__/ # 测试文件
99+
└── lib/ # 工具函数
100+
server/ # Python Flask 后端(独立运行)
101+
```
102+
103+
## 常用命令
104+
105+
```bash
106+
npm run dev # 开发服务器 (localhost:5173)
107+
npm run build # 构建
108+
npm run test:run # 单次测试
109+
npm run lint # ESLint 检查
110+
```

0 commit comments

Comments
 (0)