图片画布接入 3D 资源:新增 model3d 类别、3D 预览与 3D 生成入口
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 16s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 16s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 16s
Project CI / Native shell tests (pull_request) Failing after 16s
Project CI / Frontend tests (pull_request) Failing after 7s
Project CI / Repository checks (pull_request) Failing after 12s
Project CI / AI game creator shell web tests (pull_request) Failing after 12s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 16s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 16s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 16s
Project CI / Native shell tests (pull_request) Failing after 16s
Project CI / Frontend tests (pull_request) Failing after 7s
Project CI / Repository checks (pull_request) Failing after 12s
Project CI / AI game creator shell web tests (pull_request) Failing after 12s
- 后端资源投影按 asset_kind 分叉,新增 project_editor_client_media_src 与 EDITOR_MODEL3D_ASSET_KIND:model3d 只投影预览图,模型本体只留 objectKey,预览缺失才回落历史口径 - tripo3d 存储新增按字节魔数识别模型 content_type 与扩展名映射,不采信 provider 声明与下载响应头 - editor_project_storage 把 model3d 加入 EDITOR_CANVAS_ASSET_KINDS 白名单 - 前端 CanvasAssetKind 与 image-canvas-core 类型新增 model3d:画布卡片渲染预览图或 3D 占位,类型角标新增「3D模型」,覆盖资格只在它与空类别之间成立 - 新增 model3d-preview 子目录(Model3dViewerModal / Model3dViewerModel),Tailwind 内联、不新增 CSS,失败原因分超限 / 格式不可识别 / 无 WebGL2 三类展示 - 选中工具条新增只读 preview-model3d 能力位,仅 objectKey 为空时置灰;打开预览同时选中图层并暂停画布快捷键与舞台交互 - 查看器包源对象 format 改为可选,新增「声明 Content-Type → 字节魔数 → 地址扩展名」三级格式判定并导出支持格式清单 - 导出工作流新增 3d_models/ 目录,模型下载按真实响应头 MIME 定扩展名、对象键扩展名兜底 - 新增 3D 生成入口:底部工具栏浮动子选项与文生 / 图生 3D 面板,落 projectResource + canvasCompletion,复用占位框与任务侧栏 - 3D 定价只读实时定价查询,段缺失即入口不可提交;幂等键由前端铸造,用户重试必须换键 - 新增 ADR 0003 / 0004 与实施计划、里程碑文档;更新 Tripo 技术方案、后端架构、CONTEXT 术语、decision-log 与 pitfalls - .gitignore 忽略仓库根目录手工下载的 3D 样例模型
This commit is contained in:
@@ -56,9 +56,13 @@ const EDITOR_SOUND_EFFECT_PROMPT_OPTIMIZATION_API =
|
||||
* 覆盖简化两个业务语义轮加单轮 transport retry 的服务端预算,同时为浏览器到 BFF 的
|
||||
* 悬挂连接提供有界退出;超时后走既有失败路径恢复 idle,不写回候选。
|
||||
*/
|
||||
/** 3D 提交只做校验与入队,毫秒级返回,不沿用生成链路的分钟级超时。 */
|
||||
export const EDITOR_MODEL3D_SUBMISSION_TIMEOUT_MS = 60_000;
|
||||
export const EDITOR_BACKGROUND_MUSIC_PROMPT_ASSIST_TIMEOUT_MS = 180_000;
|
||||
export const EDITOR_SOUND_EFFECT_PROMPT_OPTIMIZE_TIMEOUT_MS = 180_000;
|
||||
const EDITOR_GENERATION_PRICING_API = '/api/editor/generation-pricing';
|
||||
const EDITOR_MODEL3D_TEXT_TO_MODEL_API = '/api/assets/tripo/text-to-model';
|
||||
const EDITOR_MODEL3D_IMAGE_TO_MODEL_API = '/api/assets/tripo/image-to-model';
|
||||
const EDITOR_IMAGE_MODEL_NANOBANANA2 = 'gemini-3.1-flash-image-preview';
|
||||
const EDITOR_IMAGE_REFERENCE_LIMIT = 5;
|
||||
const EDITOR_QUICK_EDIT_REFERENCE_LIMIT = 9;
|
||||
@@ -715,8 +719,32 @@ export type EditorGenerationModelPricing = {
|
||||
prices?: Record<string, number>;
|
||||
};
|
||||
|
||||
export type Model3dPricingEndpoint = 'text-to-model' | 'image-to-model';
|
||||
|
||||
export type Model3dAddOnPriceKey =
|
||||
| 'hdTexture'
|
||||
| 'ultraTexture'
|
||||
| 'hdGeometry'
|
||||
| 'quadMesh'
|
||||
| 'smartLowPoly'
|
||||
| 'generateParts';
|
||||
|
||||
/**
|
||||
* 3D 生成的定价段:底价按 `endpoint × modelVersion × 是否有贴图` 拆分,
|
||||
* add-on 按请求参数判定后叠加。整段缺失即 3D 生成不可用(后端 fail closed),
|
||||
* 前端不内置任何兜底数值。
|
||||
*/
|
||||
export type Model3dPricingConfig = {
|
||||
basePrices?: Record<
|
||||
Model3dPricingEndpoint,
|
||||
Record<string, { noTexture: number; texture: number }>
|
||||
> | null;
|
||||
addOnPrices?: Partial<Record<Model3dAddOnPriceKey, number>> | null;
|
||||
};
|
||||
|
||||
export type EditorGenerationPricingConfig = {
|
||||
models: Record<string, EditorGenerationModelPricing>;
|
||||
model3d?: Model3dPricingConfig | null;
|
||||
};
|
||||
|
||||
export type EditorProjectSnapshot = {
|
||||
@@ -1691,6 +1719,46 @@ export function optimizeEditorSoundEffectPrompt(
|
||||
);
|
||||
}
|
||||
|
||||
export type Model3dGenerationSubmissionResponse = {
|
||||
operationId: string;
|
||||
jobKind: string;
|
||||
status: ExternalGenerationJobStatusRecord;
|
||||
statusUrl: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 3D 生成提交:两个端点都要求 `Idempotency-Key`,键由调用方铸造并与当次请求内容绑定。
|
||||
* 这里是画布链路里唯一发送该请求头的生成入口。
|
||||
*/
|
||||
export async function submitModel3dGenerationRequest({
|
||||
endpoint,
|
||||
body,
|
||||
idempotencyKey,
|
||||
}: {
|
||||
endpoint: Model3dPricingEndpoint;
|
||||
body: Record<string, unknown>;
|
||||
idempotencyKey: string;
|
||||
}) {
|
||||
return requestJson<Model3dGenerationSubmissionResponse>(
|
||||
endpoint === 'image-to-model'
|
||||
? EDITOR_MODEL3D_IMAGE_TO_MODEL_API
|
||||
: EDITOR_MODEL3D_TEXT_TO_MODEL_API,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Idempotency-Key': idempotencyKey,
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
'提交 3D 模型生成失败',
|
||||
{
|
||||
timeoutMs: EDITOR_MODEL3D_SUBMISSION_TIMEOUT_MS,
|
||||
...EDITOR_GENERATION_REQUEST_RETRY_OPTIONS,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateEditorBackgroundMusic(
|
||||
input: EditorBackgroundMusicGenerationInput,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user