feat: 完成 O 群組 — 立繪子系統
後端(apps/api/src/tachie/):立繪 manifest(身體姿勢/服裝/表情眉眼口/ 效果層/微動態的資產目錄,服裝目錄有 M-1 登錄時優先採用);表情解析依 情緒引擎六狀態對照眉/眼/口/效果/姿勢,依 RelationshipStage 分層解鎖 (陌生~認識/朋友/摯友/羈絆,哭臉限羈絆才會出現),依角色外顯度縮放 差分幅度(magnitude = expressiveness × 情緒強度);emotionTag(實際 套用)與 rawEmotionTag(情緒引擎真實判定)分離,讓文字生成與表情解析 維持兩條獨立資料流,「文字與立繪故意不一致」是這個設計的自然結果, 不需要額外邏輯;視線方向依思考/迴避/警戒切換。 前端(apps/web/components/TachieStage.tsx):以 PixiJS 實作分層合成 與眨眼/呼吸微動態,預留 TachieRenderer 介面供未來 Live2D Cubism SDK 實作(未引入任何 Live2D 相依或授權,純架構佔位);接上 ChatView 取代 H 群組的佔位立繪,聊天回應後先查詢表情、延遲約 220ms 才顯示文字, 在非串流架構下盡力模擬「表情先變化、文字後出現」。 以 scratchpad 暫裝 playwright-core 實測瀏覽器行為(本環境無 chromium-cli),確認情緒變化即時反映在立繪、微動態持續運作。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
eccdcba45c
commit
0f3d16059c
@@ -49,3 +49,28 @@ export async function endChatSession(sessionId: string, characterId: string): Pr
|
||||
body: JSON.stringify({ characterId }),
|
||||
});
|
||||
}
|
||||
|
||||
export interface TachieExpressionResponse {
|
||||
emotionTag: EmotionTag;
|
||||
rawEmotionTag: EmotionTag;
|
||||
eyebrow: string;
|
||||
eye: string;
|
||||
mouth: string;
|
||||
effect: string | null;
|
||||
pose: string;
|
||||
magnitude: number;
|
||||
gaze: "UP" | "AWAY" | "DIRECT" | "NEUTRAL";
|
||||
availableCostumes: string[];
|
||||
lockedFallbackApplied: boolean;
|
||||
usedCryingVariant: boolean;
|
||||
}
|
||||
|
||||
// O-2 表情演出:情緒引擎已經在對話文字生成之前更新完畢,這裡獨立查詢目前的表情狀態,
|
||||
// 讓前端可以在文字訊息出現前先套用新的表情差分。
|
||||
export async function fetchExpression(characterId: string, userId: string): Promise<TachieExpressionResponse> {
|
||||
const res = await fetch(`${API_BASE_URL}/tachie/${characterId}/${userId}/expression`);
|
||||
if (!res.ok) {
|
||||
throw new Error(`表情查詢失敗(${res.status})`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user