This commit is contained in:
2026-05-13 00:28:07 +08:00
parent ef4f91a75e
commit 01c5ab985a
101 changed files with 10635 additions and 2292 deletions

View File

@@ -35,7 +35,7 @@ export type MiniGameDraftGenerationPhase =
| 'match3d-material-sheet'
| 'match3d-slice-images'
| 'match3d-upload-images'
| 'match3d-generate-models'
| 'match3d-generate-views'
| 'match3d-ready'
| 'puzzle-images'
| 'puzzle-select-image'
@@ -151,31 +151,31 @@ const MATCH3D_STEPS = [
{
id: 'match3d-item-names',
label: '生成物品名称',
detail: '根据题材生成本局的 3 个物品名称。',
detail: '根据难度生成本局物品名称。',
weight: 8,
},
{
id: 'match3d-material-sheet',
label: '生成素材图',
detail: '生成一张 1:1 的网格素材图。',
detail: '按 1K 参数分批生成 5x5 多视角素材图。',
weight: 18,
},
{
id: 'match3d-slice-images',
label: '切割独立图片',
detail: '把素材图切成独立物品参考图。',
detail: '把素材图切成每个物品的五个视角。',
weight: 8,
},
{
id: 'match3d-upload-images',
label: '上传图片资产',
detail: '写入素材图和独立物品参考图。',
detail: '写入独立 2D 视角素材。',
weight: 8,
},
{
id: 'match3d-generate-models',
label: '生成3D模型',
detail: '调用 Hyper3D Rodin 生成 GLB 模型并转存。',
id: 'match3d-generate-views',
label: '整理素材',
detail: '校验多视角素材并按需并行生成点击音效。',
weight: 50,
},
] as const satisfies ReadonlyArray<MiniGameStepDefinition>;
@@ -188,7 +188,7 @@ const MATCH3D_PHASE_ORDER: Partial<
'match3d-material-sheet': 2,
'match3d-slice-images': 3,
'match3d-upload-images': 4,
'match3d-generate-models': 5,
'match3d-generate-views': 5,
};
function clampProgress(value: number) {
@@ -298,7 +298,7 @@ function resolveMatch3DPhaseByElapsedMs(
): MiniGameDraftGenerationPhase {
const elapsedPhase =
elapsedMs >= 92_000
? 'match3d-generate-models'
? 'match3d-generate-views'
: elapsedMs >= 72_000
? 'match3d-upload-images'
: elapsedMs >= 58_000
@@ -552,7 +552,9 @@ export function buildMatch3DGenerationAnchorEntries(
}
const config = session?.config;
const itemCount = 3;
const clearCount = formPayload?.clearCount ?? config?.clearCount ?? null;
const difficulty = formPayload?.difficulty ?? config?.difficulty ?? null;
const itemCount = resolveMatch3DGeneratedItemCount(clearCount, difficulty);
const entries: Array<MiniGameAnchorSource | null> = [
{
key: 'match3d-theme',
@@ -580,6 +582,24 @@ export function buildMatch3DGenerationAnchorEntries(
.filter((entry) => entry.value.trim());
}
function resolveMatch3DGeneratedItemCount(
clearCount: number | null | undefined,
difficulty: number | null | undefined,
) {
if (clearCount === 8) return 3;
if (clearCount === 12) return 9;
if (clearCount === 16) return 15;
if (clearCount === 20 || clearCount === 21) return 21;
const normalizedDifficulty =
typeof difficulty === 'number' && Number.isFinite(difficulty)
? Math.max(1, Math.min(10, Math.round(difficulty)))
: 4;
if (normalizedDifficulty <= 2) return 3;
if (normalizedDifficulty <= 4) return 9;
if (normalizedDifficulty <= 6) return 15;
return 21;
}
export function buildSquareHoleGenerationAnchorEntries(
session: SquareHoleSessionSnapshot | null | undefined,
): CustomWorldStructuredAnchorEntry[] {