feat(scene): 场景选择与物理落地 + 整包发布(T-WIN-012/013/014)
T-WIN-013:API 升级与场景选择 - 契约快照同步到 rest-api 0.5.0 / data-models 0.7.0 / database 0.4.0 - catalog_types.gd 新增 SceneConfig(物理/环境/出生点/相机)与 Scene; CatalogBundle 增加 scenes[];from_dict 按契约 7.1 再收敛一次 (缺项默认、越界夹紧、非法枚举回退),与服务端 normalizeSceneConfig 同规则 - 新增 src/scene/scene_runtime.gd:GLB 载入 -> 碰撞体(mesh 三角网 / auto 命名约定 *_col、*_colonly / none 不兜底)-> 场景级重力(Area3D SPACE_OVERRIDE_REPLACE,不改全局 ProjectSettings)-> 风(每物理帧 apply_central_force,阵风正弦叠加,支持 local 坐标系)-> 环境光与雾 -> 出生点与相机(follow/fixed/orbit);无碰撞体时兜底地面 - CatalogStore 增加 scenes/default_scene/find_scene/ensure_scene_cached/ fetch_thumbnail(场景缓存带 sha256 指纹,避免换包后仍用旧 GLB) - 主界面改为 2x2 四个选择器(曲目/动作/模型/场景)+ 场景参数面板 (缩略图 + 重力/摩擦/弹性/碰撞体/风摘要) - 游戏界面载入场景并落地物理,角色落在出生点;场景缺失/下载失败/ 解析失败一律回退内置空场景并提示,不阻塞开始跟练 T-WIN-012:「关于」清单展示当前版本号 - 版本唯一来源为 project.godot 的 application/config/version(v0.2.0) - about_manifest() 输出版本/引擎/契约/协议/地址/隐私清单; 无头测试无 autoload,读取 AppConfig 走 get_node_or_null 容错 - Credits 的单个 CONTRACT_VERSION 常量改为 CONTRACT_VERSIONS 字典 (六项契约各自独立递增),并双向核对 contracts/VERSION T-WIN-014:发布必须是单个完整包 - build/package-release.sh 重写:只产出单个 zip + SHA256SUMS, 清理历史 .partN,超限时告警而非回退分卷;新增源产物与解压后完整性 自检(PE 头 MZ / pck 魔数 GDPC / exe+pck 同目录同名)与体积-上限对比 - deploy/proxy 相关的 Gitea IIS 256MB 上限说明见 opendance-web 测试:tests/test_scene_config.gd(12 例)+ tests/test_about.gd(4 例); 无头测试 687 通过 / 0 失败(10 个套件),verify.sh 全部通过
This commit is contained in:
@@ -940,4 +940,96 @@ components:
|
||||
songs: { type: array, items: { $ref: '#/components/schemas/Song' } }
|
||||
motions: { type: array, items: { $ref: '#/components/schemas/Motion' } }
|
||||
models: { type: array, items: { $ref: '#/components/schemas/Model' } }
|
||||
scenes:
|
||||
type: array
|
||||
description: 已发布场景(rest-api 0.5.0 起随目录下发;结构见 data-models.md 7)
|
||||
items: { $ref: '#/components/schemas/Scene' }
|
||||
defaultModelId: { type: integer, format: int64, nullable: true }
|
||||
|
||||
Scene:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SourceFields'
|
||||
- type: object
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
name: { type: string }
|
||||
glbUrl: { type: string, nullable: true, description: 场景 GLB 下载地址 }
|
||||
thumbnailUrl: { type: string, nullable: true }
|
||||
fileSize: { type: integer, nullable: true }
|
||||
fileSha256: { type: string, nullable: true }
|
||||
conversionNote:
|
||||
type: string
|
||||
nullable: true
|
||||
description: 由 .zip/.pmx/.fbx 转换而来时的说明;直接上传 GLB 为 null
|
||||
config:
|
||||
allOf: [{ $ref: '#/components/schemas/SceneConfig' }]
|
||||
nullable: true
|
||||
description: 物理 / 环境 / 出生点 / 相机;服务端只存参数,仿真在客户端
|
||||
stats:
|
||||
type: object
|
||||
nullable: true
|
||||
description: 场景 GLB 分析(面数 / 网格 / 材质 / warnings)
|
||||
status: { $ref: '#/components/schemas/PublishStatus' }
|
||||
createdAt: { type: string, format: date-time }
|
||||
updatedAt: { type: string, format: date-time }
|
||||
|
||||
SceneConfig:
|
||||
type: object
|
||||
description: >-
|
||||
data-models.md 7.1 冻结结构。服务端入库时对每项做边界收敛
|
||||
(越界夹紧、非法枚举回退默认值),客户端拿到的参数一定可解释。
|
||||
properties:
|
||||
physics:
|
||||
type: object
|
||||
properties:
|
||||
gravity:
|
||||
type: object
|
||||
description: 米/秒^2,各分量 ±200
|
||||
properties:
|
||||
x: { type: number }
|
||||
y: { type: number }
|
||||
z: { type: number }
|
||||
wind:
|
||||
type: object
|
||||
properties:
|
||||
base: { $ref: '#/components/schemas/Vec3' }
|
||||
gustAmplitude: { type: number, description: 0~100 }
|
||||
gustFrequency: { type: number, description: Hz,0.01~5 }
|
||||
gustDirection: { $ref: '#/components/schemas/Vec3' }
|
||||
space: { type: string, enum: [world, local] }
|
||||
ground:
|
||||
type: object
|
||||
properties:
|
||||
friction: { type: number, description: 0~1 }
|
||||
restitution: { type: number, description: 0~1 }
|
||||
slopeLimit: { type: number, description: 0~89 度 }
|
||||
colliders: { type: string, enum: [auto, mesh, none] }
|
||||
environment:
|
||||
type: object
|
||||
properties:
|
||||
ambientColor: { type: string, description: '#RRGGBB' }
|
||||
ambientIntensity: { type: number, description: 0~4 }
|
||||
fogDensity: { type: number, description: 0~1,0=关闭 }
|
||||
spawnPoints:
|
||||
type: array
|
||||
maxItems: 16
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
x: { type: number }
|
||||
y: { type: number }
|
||||
z: { type: number }
|
||||
yaw: { type: number, description: 朝向(度,绕 Y 轴) }
|
||||
camera:
|
||||
type: object
|
||||
properties:
|
||||
mode: { type: string, enum: [follow, fixed, orbit] }
|
||||
distance: { type: number, description: 0.5~50 }
|
||||
height: { type: number, description: 0~20 }
|
||||
|
||||
Vec3:
|
||||
type: object
|
||||
properties:
|
||||
x: { type: number }
|
||||
y: { type: number }
|
||||
z: { type: number }
|
||||
|
||||
Reference in New Issue
Block a user