From ae044f61d2622aceafa659c72cca525513b61fb2 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Wed, 18 Mar 2026 14:37:55 +0800 Subject: [PATCH] feat: load 3D blueprint from MD file instead of hardcoded data --- src/components/blueprint/DetailPanel.tsx | 29 +- src/data/blueprintParser.ts | 231 +++++++ src/data/sampleData.ts | 180 ----- src/docs/blueprint.md | 804 +++++++++++++++++++++++ src/store/blueprintStore.ts | 5 +- tsconfig.tsbuildinfo | 2 +- 6 files changed, 1065 insertions(+), 186 deletions(-) create mode 100644 src/data/blueprintParser.ts delete mode 100644 src/data/sampleData.ts create mode 100644 src/docs/blueprint.md diff --git a/src/components/blueprint/DetailPanel.tsx b/src/components/blueprint/DetailPanel.tsx index aebc6e5..fbd7c91 100644 --- a/src/components/blueprint/DetailPanel.tsx +++ b/src/components/blueprint/DetailPanel.tsx @@ -69,7 +69,7 @@ export default function DetailPanel() { {subsystem.depends_on.length > 0 && ( -
+
Depends On
{subsystem.depends_on.map((d, i) => ( @@ -78,6 +78,31 @@ export default function DetailPanel() {
)} + + {subsystem.boundary && ( +
+ {subsystem.boundary.inputs.length > 0 && ( +
+
Inputs
+
+ {subsystem.boundary.inputs.map((input, i) => ( + {input} + ))} +
+
+ )} + {subsystem.boundary.outputs.length > 0 && ( +
+
Outputs
+
+ {subsystem.boundary.outputs.map((output, i) => ( + {output} + ))} +
+
+ )} +
+ )} )} @@ -105,7 +130,7 @@ export default function DetailPanel() { params: {api.params.map(p => p.name).join(', ') || 'none'}
- returns: {api.returns.type} + returns: {api.returns?.type || 'void'}
))} diff --git a/src/data/blueprintParser.ts b/src/data/blueprintParser.ts new file mode 100644 index 0000000..08f8feb --- /dev/null +++ b/src/data/blueprintParser.ts @@ -0,0 +1,231 @@ +import blueprintMd from '../docs/blueprint.md?raw'; + +export interface Boundary { + inputs: string[]; + outputs: string[]; +} + +export interface Subsystem { + id: string; + name: string; + responsibilities: string[]; + provides: string[]; + depends_on: string[]; + boundary?: Boundary; +} + +export interface Module { + id: string; + name: string; + parent_subsystem: string; + responsibility: string; + public_api: { + fn: string; + params: { name: string; type: string }[]; + returns?: { type: string }; + }[]; +} + +export interface SystemMeta { + name: string; + version: string; + type: string; + description: string; + target_runtime: string; +} + +export interface BlueprintData { + meta: SystemMeta; + subsystems: Subsystem[]; + modules: Module[]; +} + +function extractYamlBlock(markdown: string, sectionName: string): string { + const pattern = new RegExp(`# ${sectionName}[\\s\\S]*?\`\`\`yaml\\n([\\s\\S]*?)\n\`\`\``, 'i'); + const match = markdown.match(pattern); + return match ? match[1].trim() : ''; +} + +function parseSubsystemList(yaml: string): Subsystem[] { + const subsystems: Subsystem[] = []; + const lines = yaml.split('\n'); + let currentSubsystem: Partial | null = null; + let currentField = ''; + let currentList: string[] = []; + + for (const line of lines) { + if (line.includes('- name:')) { + if (currentSubsystem && currentSubsystem.name) { + subsystems.push({ + id: currentSubsystem.name, + name: currentSubsystem.name, + responsibilities: currentSubsystem.responsibilities || [], + provides: currentSubsystem.provides || [], + depends_on: currentSubsystem.depends_on || [], + boundary: currentSubsystem.boundary + }); + } + currentSubsystem = { name: line.split('- name:')[1].trim() }; + currentField = ''; + currentList = []; + } else if (currentSubsystem && line.includes('responsibilities:')) { + currentField = 'responsibilities'; + currentList = []; + } else if (currentSubsystem && line.includes('provides:')) { + currentField = 'provides'; + currentList = []; + } else if (currentSubsystem && line.includes('depends_on:')) { + currentField = 'depends_on'; + currentList = []; + } else if (currentSubsystem && line.includes('boundary:')) { + currentField = 'boundary'; + currentSubsystem.boundary = { inputs: [], outputs: [] }; + } else if (currentSubsystem && currentField === 'responsibilities' && line.includes('-')) { + const val = line.replace('-', '').trim().replace(/"/g, ''); + if (val) currentList.push(val); + currentSubsystem.responsibilities = [...currentList]; + } else if (currentSubsystem && currentField === 'provides' && line.includes('[')) { + const match = line.match(/\[(.*?)\]/); + if (match) { + currentSubsystem.provides = match[1].split(',').map(s => s.trim()); + } + } else if (currentSubsystem && currentField === 'depends_on' && line.includes('[')) { + const match = line.match(/\[(.*?)\]/); + if (match && match[1].trim()) { + currentSubsystem.depends_on = match[1].split(',').map(s => s.trim()); + } else { + currentSubsystem.depends_on = []; + } + } else if (currentSubsystem && currentField === 'boundary' && line.includes('inputs:')) { + const match = line.match(/\[(.*?)\]/); + if (match) { + currentSubsystem.boundary!.inputs = match[1].split(',').map(s => s.trim()); + } + } else if (currentSubsystem && currentField === 'boundary' && line.includes('outputs:')) { + const match = line.match(/\[(.*?)\]/); + if (match) { + currentSubsystem.boundary!.outputs = match[1].split(',').map(s => s.trim()); + } + } + } + + if (currentSubsystem && currentSubsystem.name) { + subsystems.push({ + id: currentSubsystem.name, + name: currentSubsystem.name, + responsibilities: currentSubsystem.responsibilities || [], + provides: currentSubsystem.provides || [], + depends_on: currentSubsystem.depends_on || [], + boundary: currentSubsystem.boundary + }); + } + + return subsystems; +} + +function parseModuleList(yaml: string): Module[] { + const modules: Module[] = []; + const lines = yaml.split('\n'); + let currentModule: Partial | null = null; + let currentApi: { fn: string; params: { name: string; type: string }[]; returns?: { type: string } } | null = null; + let inPublicApi = false; + let currentField = ''; + + for (const line of lines) { + if (line.includes('- name:') && line.includes('parent_subsystem:')) { + if (currentModule && currentModule.name && currentModule.parent_subsystem) { + modules.push({ + id: currentModule.name, + name: currentModule.name, + parent_subsystem: currentModule.parent_subsystem, + responsibility: currentModule.responsibility || '', + public_api: currentModule.public_api || [] + }); + } + const nameMatch = line.match(/- name:\s*(\S+)/); + const parentMatch = line.match(/parent_subsystem:\s*(\S+)/); + currentModule = { + name: nameMatch ? nameMatch[1] : '', + parent_subsystem: parentMatch ? parentMatch[1] : '', + public_api: [] + }; + inPublicApi = false; + } else if (currentModule && line.includes('responsibility:')) { + const match = line.match(/responsibility:\s*"(.+)"/); + if (match) { + currentModule.responsibility = match[1]; + } + } else if (currentModule && line.includes('public_api:')) { + inPublicApi = true; + } else if (currentModule && inPublicApi && line.includes('- fn:')) { + const fnMatch = line.match(/- fn:\s*(\S+)/); + if (fnMatch) { + currentApi = { fn: fnMatch[1], params: [] }; + currentModule.public_api = currentModule.public_api || []; + currentModule.public_api.push(currentApi); + } + } else if (currentModule && currentApi && line.includes('params:')) { + currentField = 'params'; + } else if (currentModule && currentApi && line.includes('returns:')) { + currentField = 'returns'; + const returnsMatch = line.match(/returns:\s*type:\s*(\S+)/); + if (returnsMatch) { + currentApi.returns = { type: returnsMatch[1] }; + } + } else if (currentModule && currentApi && currentField === 'params' && line.includes('name:')) { + const nameMatch = line.match(/name:\s*(\S+)/); + const typeMatch = line.match(/type:\s*(\S+)/); + if (nameMatch && typeMatch) { + currentApi.params.push({ name: nameMatch[1], type: typeMatch[1] }); + } + } + } + + if (currentModule && currentModule.name) { + modules.push({ + id: currentModule.name, + name: currentModule.name, + parent_subsystem: currentModule.parent_subsystem || '', + responsibility: currentModule.responsibility || '', + public_api: currentModule.public_api || [] + }); + } + + return modules; +} + +export function parseBlueprintFromMd(markdown: string): BlueprintData { + const metaYaml = extractYamlBlock(markdown, 'SYSTEM_META'); + const structureYaml = extractYamlBlock(markdown, 'SYSTEM_STRUCTURE'); + + const meta: SystemMeta = { + name: 'Unknown', + version: '0.0.0', + type: 'unknown', + description: '', + target_runtime: '' + }; + + const metaLines = metaYaml.split('\n'); + for (const line of metaLines) { + if (line.includes('name:')) { + meta.name = line.split('name:')[1].trim().replace(/"/g, ''); + } else if (line.includes('version:')) { + const ver = line.split('version:')[1].trim(); + meta.version = ver; + } else if (line.includes('type:')) { + meta.type = line.split('type:')[1].trim().replace(/"/g, ''); + } else if (line.includes('description:')) { + meta.description = line.split('description:')[1].trim().replace(/"/g, ''); + } else if (line.includes('target_runtime:')) { + meta.target_runtime = line.split('target_runtime:')[1].trim().replace(/"/g, ''); + } + } + + const subsystems = parseSubsystemList(structureYaml); + const modules = parseModuleList(structureYaml); + + return { meta, subsystems, modules }; +} + +export const blueprintData = parseBlueprintFromMd(blueprintMd); diff --git a/src/data/sampleData.ts b/src/data/sampleData.ts deleted file mode 100644 index f06a6e0..0000000 --- a/src/data/sampleData.ts +++ /dev/null @@ -1,180 +0,0 @@ -export interface Subsystem { - id: string; - name: string; - responsibilities: string[]; - provides: string[]; - depends_on: string[]; -} - -export interface Module { - id: string; - name: string; - parent_subsystem: string; - responsibility: string; - public_api: { - fn: string; - params: { name: string; type: string }[]; - returns: { type: string }; - }[]; -} - -export interface SystemMeta { - name: string; - version: string; - type: string; - description: string; - target_runtime: string; -} - -export interface BlueprintData { - meta: SystemMeta; - subsystems: Subsystem[]; - modules: Module[]; -} - -export const sampleBlueprint: BlueprintData = { - meta: { - name: 'UnityEngine', - version: '0.1.0', - type: 'game-engine', - description: '轻量级3D游戏引擎,支持场景管理、渲染、物理、脚本系统', - target_runtime: 'C++17 / C#' - }, - subsystems: [ - { - id: 'Core', - name: 'Core', - responsibilities: ['基础数据类型和算法', '内存管理', '平台抽象层'], - provides: ['IAllocator', 'IPlatform', 'IFileSystem'], - depends_on: [] - }, - { - id: 'Rendering', - name: 'Rendering', - responsibilities: ['渲染管线管理', '渲染资源管理', 'Shader管理', 'Camera管理'], - provides: ['IRenderPipeline', 'IRenderResource', 'IShader', 'ICamera'], - depends_on: ['Core'] - }, - { - id: 'Physics', - name: 'Physics', - responsibilities: ['物理模拟', '碰撞检测', '刚体/关节系统'], - provides: ['IPhysicsWorld', 'ICollider', 'IRigidbody'], - depends_on: ['Core'] - }, - { - id: 'Scripting', - name: 'Scripting', - responsibilities: ['脚本生命周期管理', 'C#运行时集成', '组件系统'], - provides: ['IScriptRuntime', 'IMonoBehaviour', 'IComponent'], - depends_on: ['Core'] - }, - { - id: 'Scene', - name: 'Scene', - responsibilities: ['场景图管理', 'GameObject层级管理', '变换层级'], - provides: ['IScene', 'IGameObject', 'ITransform'], - depends_on: ['Core'] - }, - { - id: 'Asset', - name: 'Asset', - responsibilities: ['资源加载/卸载', '资源引用计数', '资源格式支持'], - provides: ['IAssetLoader', 'IAssetDatabase'], - depends_on: ['Core'] - }, - { - id: 'Input', - name: 'Input', - responsibilities: ['输入事件采集', '输入映射'], - provides: ['IInputSystem'], - depends_on: ['Core'] - }, - { - id: 'Platform', - name: 'Platform', - responsibilities: ['平台特定实现', '窗口管理', '主循环'], - provides: ['IWindow', 'IApplication'], - depends_on: ['Core'] - } - ], - modules: [ - { - id: 'RHI', - name: 'RHI', - parent_subsystem: 'Rendering', - responsibility: '渲染硬件抽象层', - public_api: [ - { fn: 'CreateGraphicsPipeline', params: [{ name: 'desc', type: 'GraphicsPipelineDesc' }], returns: { type: 'IPipeline' } }, - { fn: 'Draw', params: [{ name: 'pipeline', type: 'IPipeline' }, { name: 'mesh', type: 'IMesh' }], returns: { type: 'void' } } - ] - }, - { - id: 'RenderPipeline', - name: 'RenderPipeline', - parent_subsystem: 'Rendering', - responsibility: '渲染管线调度', - public_api: [ - { fn: 'Render', params: [{ name: 'scene', type: 'IScene' }, { name: 'camera', type: 'ICamera' }], returns: { type: 'void' } } - ] - }, - { - id: 'ShaderManager', - name: 'ShaderManager', - parent_subsystem: 'Rendering', - responsibility: 'Shader编译和缓存', - public_api: [ - { fn: 'LoadShader', params: [{ name: 'path', type: 'string' }], returns: { type: 'IShader' } } - ] - }, - { - id: 'PhysicsWorld', - name: 'PhysicsWorld', - parent_subsystem: 'Physics', - responsibility: '物理世界模拟', - public_api: [ - { fn: 'Step', params: [{ name: 'dt', type: 'float' }], returns: { type: 'void' } } - ] - }, - { - id: 'MonoBehaviour', - name: 'MonoBehaviour', - parent_subsystem: 'Scripting', - responsibility: '脚本组件基类', - public_api: [ - { fn: 'Awake', params: [], returns: { type: 'void' } }, - { fn: 'Start', params: [], returns: { type: 'void' } }, - { fn: 'Update', params: [{ name: 'dt', type: 'float' }], returns: { type: 'void' } } - ] - }, - { - id: 'Transform', - name: 'Transform', - parent_subsystem: 'Scene', - responsibility: '变换层级管理', - public_api: [ - { fn: 'SetParent', params: [{ name: 'parent', type: 'ITransform' }], returns: { type: 'void' } }, - { fn: 'LocalToWorld', params: [{ name: 'localPos', type: 'vec3' }], returns: { type: 'vec3' } } - ] - }, - { - id: 'GameObject', - name: 'GameObject', - parent_subsystem: 'Scene', - responsibility: '场景对象管理', - public_api: [ - { fn: 'AddComponent', params: [{ name: 'type', type: 'type_info' }], returns: { type: 'IComponent' } }, - { fn: 'GetComponent', params: [{ name: 'type', type: 'type_info' }], returns: { type: 'IComponent' } } - ] - }, - { - id: 'AssetLoader', - name: 'AssetLoader', - parent_subsystem: 'Asset', - responsibility: '资源异步加载', - public_api: [ - { fn: 'LoadAsync', params: [{ name: 'path', type: 'string' }], returns: { type: 'AssetFuture' } } - ] - } - ] -}; diff --git a/src/docs/blueprint.md b/src/docs/blueprint.md new file mode 100644 index 0000000..83badb2 --- /dev/null +++ b/src/docs/blueprint.md @@ -0,0 +1,804 @@ +# UnityEngine 蓝图示例 + +--- + +# SYSTEM_META + +```yaml +name: UnityEngine +version: 0.1.0 +type: game-engine +description: "轻量级3D游戏引擎,支持场景管理、渲染、物理、脚本系统" +target_runtime: C++17 / C# +``` + +--- + +# SYSTEM_STRUCTURE + +```yaml +root: UnityEngine + +subsystems: + - name: Core + responsibilities: + - "基础数据类型和算法" + - "内存管理" + - "平台抽象层" + provides: [IAllocator, IPlatform, IFileSystem] + depends_on: [] + boundary: + inputs: [] + outputs: [] + + - name: Rendering + responsibilities: + - "渲染管线管理" + - "渲染资源管理" + - "Shader管理" + - "Camera管理" + provides: [IRenderPipeline, IRenderResource, IShader, ICamera] + depends_on: [Core] + boundary: + inputs: [Scene, Camera, Light] + outputs: [FrameBuffer, Texture] + + - name: Physics + responsibilities: + - "物理模拟" + - "碰撞检测" + - "刚体/关节系统" + provides: [IPhysicsWorld, ICollider, IRigidbody] + depends_on: [Core] + boundary: + inputs: [Transform, Collider] + outputs: [PhysicsState, Contact] + + - name: Scripting + responsibilities: + - "脚本生命周期管理" + - "C#运行时集成" + - "组件系统" + provides: [IScriptRuntime, IMonoBehaviour, IComponent] + depends_on: [Core] + boundary: + inputs: [Script, GameObject] + outputs: [ComponentInstance] + + - name: Scene + responsibilities: + - "场景图管理" + - "GameObject层级管理" + - "变换层级" + provides: [IScene, IGameObject, ITransform] + depends_on: [Core] + boundary: + inputs: [] + outputs: [SceneGraph] + + - name: Asset + responsibilities: + - "资源加载/卸载" + - "资源引用计数" + - "资源格式支持" + provides: [IAssetLoader, IAssetDatabase] + depends_on: [Core] + boundary: + inputs: [AssetPath] + outputs: [Asset, Texture, Mesh, Material] + + - name: Input + responsibilities: + - "输入事件采集" + - "输入映射" + provides: [IInputSystem] + depends_on: [Core] + boundary: + inputs: [HardwareInput] + outputs: [InputEvent] + + - name: Platform + responsibilities: + - "平台特定实现" + - "窗口管理" + - "主循环" + provides: [IWindow, IApplication] + depends_on: [Core] + boundary: + inputs: [] + outputs: [] + +modules: + - name: RHI + parent_subsystem: Rendering + responsibility: "渲染硬件抽象层" + public_api: + - fn: CreateGraphicsPipeline + params: + - name: desc + type: GraphicsPipelineDesc + returns: type: IPipeline + + - fn: Draw + params: + - name: pipeline + type: IPipeline + - name: mesh + type: IMesh + - name: material + type: IMaterial + + - fn: Execute + params: [] + + - name: RenderPipeline + parent_subsystem: Rendering + responsibility: "渲染管线调度" + public_api: + - fn: Render + params: + - name: scene + type: IScene + - name: camera + type: ICamera + + - name: ShaderManager + parent_subsystem: Rendering + responsibility: "Shader编译和缓存" + public_api: + - fn: LoadShader + params: + - name: path + type: string + returns: type: IShader + + - name: PhysicsWorld + parent_subsystem: Physics + responsibility: "物理世界模拟" + public_api: + - fn: Step + params: + - name: dt + type: float + + - name: MonoBehaviour + parent_subsystem: Scripting + responsibility: "脚本组件基类" + public_api: + - fn: Awake + params: [] + - fn: Start + params: [] + - fn: Update + params: + - name: dt + type: float + + - name: Transform + parent_subsystem: Scene + responsibility: "变换层级管理" + public_api: + - fn: SetParent + params: + - name: parent + type: ITransform + + - fn: LocalToWorld + params: + - name: localPos + type: vec3 + + - name: AssetLoader + parent_subsystem: Asset + responsibility: "资源异步加载" + public_api: + - fn: LoadAsync + params: + - name: path + type: string + returns: type: AssetFuture + + - name: GameObject + parent_subsystem: Scene + responsibility: "场景对象管理" + public_api: + - fn: AddComponent + params: + - name: type + type: type_info + returns: type: IComponent + + - fn: GetComponent + params: + - name: type + type: type_info + returns: type: IComponent +``` + +--- + +# EVOLUTION_MODE + +```yaml +mode: build +description: "从0开始构建引擎核心功能" +context: | + 构建一个最小可用的3D游戏引擎 + 优先实现渲染和场景管理,其他子系统后续迭代 +``` + +--- + +# REQUIREMENTS + +```yaml +- id: REQ-001 + title: 窗口创建和主循环 + description: "应用启动后创建窗口并进入主循环" + source: user + type: functional + acceptance_criteria: + - "窗口正常创建并显示" + - "主循环持续运行" + - "窗口关闭后程序正常退出" + priority: P0 + +- id: REQ-002 + title: 渲染立方体 + description: "在屏幕上渲染一个简单的立方体" + source: user + type: functional + acceptance_criteria: + - "立方体几何数据正确" + - "Basic Shader能编译" + - "立方体正确显示在屏幕中央" + priority: P0 + +- id: REQ-003 + title: 相机支持 + description: "支持透视相机,可控制视角" + source: user + type: functional + acceptance_criteria: + - "Camera组件存在" + - "支持投影矩阵设置" + - "可通过鼠标/键盘控制视角" + priority: P0 + +- id: REQ-004 + title: 场景图管理 + description: "GameObject层级关系正确,父子变换生效" + source: user + type: functional + acceptance_criteria: + - "可创建GameObject" + - "可设置父子关系" + - "子对象随父对象移动" + priority: P0 + +- id: REQ-005 + title: 资源加载 + description: "能够加载外部模型和纹理" + source: user + type: functional + acceptance_criteria: + - "支持加载PNG/JPG图片" + - "支持加载OBJ模型" + - "加载显示在场景中" + priority: P1 + +- id: REQ-006 + title: 物理模拟 + description: "简单的重力物理效果" + source: user + type: functional + acceptance_criteria: + - "物体受重力下落" + - "支持AABB碰撞检测" + priority: P1 + +- id: REQ-007 + title: 组件系统 + description: "支持MonoBehaviour脚本组件" + source: user + type: functional + acceptance_criteria: + - "可创建C#脚本组件" + - "Awake/Start/Update生命周期正确" + priority: P2 + +- id: REQ-NF-001 + title: 跨平台支持 + description: "支持Windows/Linux/macOS" + source: constraint + type: non-functional + acceptance_criteria: + - "同一代码可在三平台编译" + - "核心功能在各平台工作一致" + priority: P1 + +- id: REQ-NF-002 + title: 60FPS性能 + description: "简单场景达到60FPS" + source: constraint + type: non-functional + acceptance_criteria: + - "空场景 > 1000 FPS" + - "100个简单对象 > 60 FPS" + priority: P1 +``` + +--- + +# MVS_DEFINITION + +```yaml +mvs_solutions: + - id: MVS-001 + name: 最小渲染验证 + goal: "验证RHI可正常调用,渲染一个三角形到屏幕" + + verification_criteria: + - "程序启动后显示黑色窗口" + - "窗口显示一个彩色三角形" + - "窗口可正常关闭" + + scope: + - subsystem: Core + components: [Allocator, FileSystem] + - subsystem: Platform + components: [Window, Application] + - subsystem: Rendering + components: [RHI] + - external: [VulkanSDK, GLFW] + + code_structure: + - file: mvs_main.cpp + purpose: "入口,直接创建RHI,渲染三角形" + contains: + - "初始化GLFW窗口" + - "初始化Vulkan" + - "创建简单顶点缓冲" + - "渲染循环绘制三角形" + standalone: true + + - file: mvs_shader.vert + purpose: "顶点着色器" + contains: ["顶点位置传递到片段着色器"] + + - file: mvs_shader.frag + purpose: "片段着色器" + contains: ["输出固定颜色"] + + integration_plan: + - step: "将RHI相关代码移到Rendering/RHI/模块" + - step: "创建IPlatform抽象接口" + - step: "创建Platform/Windows实现" + - step: "将主循环抽象到Application" + + status: pending + + - id: MVS-002 + name: 场景系统验证 + goal: "验证Scene/GameObject/Transform层级正确" + + verification_criteria: + - "创建两个GameObject" + - "设置父子关系" + - "父对象移动,子对象跟随" + - "控制台输出正确的变换矩阵" + + scope: + - subsystem: Core + - subsystem: Scene + components: [GameObject, Transform] + - subsystem: Platform + + code_structure: + - file: mvs_scene.cpp + purpose: "测试场景层级" + contains: + - "创建根GameObject" + - "创建子GameObject" + - "设置父对象位置" + - "打印子对象世界坐标" + + integration_plan: + - step: "将GameObject/Transform移到Scene模块" + - step: "创建SceneManager管理场景" + + status: pending + + - id: MVS-003 + name: 完整渲染验证 + goal: "验证渲染管线完整,渲染立方体+相机+光照" + + verification_criteria: + - "屏幕上渲染一个立方体" + - "相机可旋转视角" + - "有基本的光照效果" + - "帧率 > 30 FPS" + + scope: + - subsystem: Rendering + components: [RenderPipeline, ShaderManager] + - subsystem: Scene + - subsystem: Platform + + code_structure: + - file: mvs_engine.cpp + purpose: "整合各子系统进行渲染" + contains: + - "初始化所有子系统" + - "创建Cube Mesh" + - "创建Camera" + - "创建DirectionalLight" + - "渲染循环" + + integration_plan: + - step: "合并MVS-001的RHI代码" + - step: "将Platform抽象集成" + - step: "创建Engine主类统一管理" + + status: pending +``` + +--- + +# DATA_MODELS + +```yaml +- name: Vector3 + description: "3D向量" + fields: + - name: x + type: float + default: 0.0 + - name: y + type: float + default: 0.0 + - name: z + type: float + default: 0.0 + +- name: Transform + description: "变换组件数据" + fields: + - name: localPosition + type: Vector3 + default: (0,0,0) + - name: localRotation + type: Quaternion + default: identity + - name: localScale + type: Vector3 + default: (1,1,1) + - name: parent + type: Transform + constraints: optional + +- name: GameObject + description: "场景对象" + fields: + - name: name + type: string + constraints: required + - name: transform + type: Transform + - name: components + type: array + items: + type: IComponent + +- name: Camera + description: "相机组件" + fields: + - name: fov + type: float + default: 60.0 + - name: near + type: float + default: 0.1 + - name: far + type: float + default: 1000.0 + - name: projectionMatrix + type: Matrix4x4 + - name: viewMatrix + type: Matrix4x4 + +- name: Mesh + description: "网格数据" + fields: + - name: vertices + type: array + items: + type: Vector3 + - name: indices + type: array + items: + type: uint32 + - name: normals + type: array + items: + type: Vector3 + +- name: Material + description: "材质" + fields: + - name: shader + type: IShader + - name: properties + type: map + key: string + value: ShaderProperty +``` + +--- + +# TASKS + +```yaml +- id: TASK-001 + title: 项目初始化 + description: "创建项目结构、CMake配置、基础构建系统" + module: Core + output: + type: directory + path: "UnityEngine/" + verification: + - criterion: "CMakeLists.txt创建成功" + - criterion: "项目能编译成功" + priority: critical + status: pending + +- id: TASK-002 + title: 实现Core基础库 + description: "实现Vector3, Matrix4x4, Quaternion等基础数学类型" + module: Core + depends_on: [TASK-001] + output: + type: directory + path: "UnityEngine/Core/Math/" + verification: + - criterion: "单元测试覆盖基础运算" + priority: critical + status: pending + +- id: TASK-003 + title: 实现内存分配器 + description: "实现基础内存管理" + module: Core + depends_on: [TASK-001] + output: + type: file + path: "UnityEngine/Core/Memory/Allocator.h" + verification: + - criterion: "基础malloc/free正常" + priority: high + status: pending + +- id: TASK-004 + title: 实现Platform抽象层 + description: "创建IWindow, IApplication接口和基础实现" + module: Platform + depends_on: [TASK-001] + output: + type: directory + path: "UnityEngine/Platform/" + verification: + - criterion: "接口定义完整" + - criterion: "Windows实现可用" + priority: critical + status: pending + +- id: TASK-005 + title: 实现MVS-001 最小渲染 + description: "直接拼凑代码,渲染三角形" + module: RHI + depends_on: [TASK-004] + mvs_related: MVS-001 + output: + type: directory + path: "UnityEngine/MVS/mvs_001/" + verification: + - criterion: "MVS-001验收通过" + priority: critical + status: pending + +- id: TASK-006 + title: 实现Scene模块 + description: "实现GameObject, Transform, Scene基本功能" + module: Scene + depends_on: [TASK-002] + output: + type: directory + path: "UnityEngine/Scene/" + verification: + - criterion: "MVS-002验收通过" + priority: critical + status: pending + +- id: TASK-007 + title: 实现MVS-002 场景系统验证 + description: "测试场景层级功能" + module: Scene + depends_on: [TASK-006, TASK-004] + mvs_related: MVS-002 + output: + type: file + path: "UnityEngine/MVS/mvs_002/test_scene.cpp" + verification: + - criterion: "MVS-002验收通过" + priority: critical + status: pending + +- id: TASK-008 + title: 实现RHI模块 + description: "完善RHI抽象层" + module: RHI + depends_on: [TASK-005] + output: + type: directory + path: "UnityEngine/Rendering/RHI/" + verification: + - criterion: "Vulkan后端完整实现" + priority: high + status: pending + +- id: TASK-009 + title: 实现ShaderManager + description: "Shader编译和管理" + module: ShaderManager + depends_on: [TASK-008] + output: + type: file + path: "UnityEngine/Rendering/ShaderManager.h" + verification: + - criterion: "能加载和编译简单Shader" + priority: high + status: pending + +- id: TASK-010 + title: 实现RenderPipeline + description: "渲染管线调度" + module: RenderPipeline + depends_on: [TASK-008, TASK-009] + output: + type: file + path: "UnityEngine/Rendering/Pipeline.h" + verification: + - criterion: "能执行基本渲染流程" + priority: high + status: pending + +- id: TASK-011 + title: 实现Camera组件 + description: "相机投影、视角控制" + module: Camera + depends_on: [TASK-006, TASK-002] + output: + type: file + path: "UnityEngine/Scene/Component/Camera.h" + verification: + - criterion: "透视投影正确" + - criterion: "可控制视角" + priority: high + status: pending + +- id: TASK-012 + title: 实现Asset加载模块 + description: "资源加载系统" + module: AssetLoader + depends_on: [TASK-001] + output: + type: directory + path: "UnityEngine/Asset/" + verification: + - criterion: "能加载PNG/JPG" + - criterion: "能加载OBJ" + priority: medium + status: pending + +- id: TASK-013 + title: 实现MVS-003 完整渲染 + description: "整合所有子系统,渲染立方体" + module: Engine + depends_on: [TASK-010, TASK-011, TASK-012] + mvs_related: MVS-003 + output: + type: file + path: "UnityEngine/MVS/mvs_003/engine.cpp" + verification: + - criterion: "MVS-003验收通过" + priority: critical + status: pending + +- id: TASK-014 + title: 实现Physics模块 + description: "物理世界模拟" + module: PhysicsWorld + depends_on: [TASK-002] + output: + type: directory + path: "UnityEngine/Physics/" + verification: + - criterion: "MVS验证通过" + priority: medium + status: pending + +- id: TASK-015 + title: 实现Scripting模块 + description: "C#脚本运行时集成" + module: Scripting + depends_on: [TASK-001] + output: + type: directory + path: "UnityEngine/Scripting/" + verification: + - criterion: "MonoBehaviour生命周期正确" + priority: low + status: pending +``` + +--- + +# CONSTRAINTS + +```yaml +runtime: + language: C++17 + compiler: [clang, gcc, msvc] + stdlib: stl + build_system: cmake + +quality: + - "每次commit必须可编译" + - "核心模块必须有单元测试" + - "禁止裸指针,必须使用智能指针" + - "所有类必须提供虚析构函数" + +security: + - "禁止硬编码路径" + - "资源路径需验证合法性" + +performance: + - "单帧耗时 < 16ms (60FPS)" + - "内存分配使用对象池" + - "渲染调用批量提交" + +compatibility: + - "支持Windows 10+" + - "支持Linux (Ubuntu 20.04+)" + - "支持macOS 12+" + - "Vulkan 1.2+ / OpenGL 4.5+ / DirectX 12" +``` + +--- + +# EVOLUTION_PLAN + +```yaml +# 当前为build模式,暂无演化计划 +# 后续迭代时添加 + +# fix_plan: +# - issue_id: BUG-001 +# description: "..." +# root_cause: "..." +# minimal_change: +# - file: ... +# verification: ... + +# refactor_plan: +# - target: "..." +# constraints: [...] +# steps: [...] + +# feature_plan: +# - feature_id: FEAT-001 +# name: "..." +# addition: "..." +# integration_point: ... +# steps: [...] +``` diff --git a/src/store/blueprintStore.ts b/src/store/blueprintStore.ts index c5dff38..f05c65d 100644 --- a/src/store/blueprintStore.ts +++ b/src/store/blueprintStore.ts @@ -1,6 +1,5 @@ import { create } from 'zustand'; -import type { BlueprintData } from '../data/sampleData'; -import { sampleBlueprint } from '../data/sampleData'; +import { blueprintData, type BlueprintData } from '../data/blueprintParser'; interface BlueprintStore { blueprint: BlueprintData; @@ -9,7 +8,7 @@ interface BlueprintStore { } export const useBlueprintStore = create((set) => ({ - blueprint: sampleBlueprint, + blueprint: blueprintData, selectedNode: null, setSelectedNode: (id) => set({ selectedNode: id }), })); diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index 5a1d9dd..184bafe 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/app.tsx","./src/config.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/apidocviewer.tsx","./src/components/doccontent.tsx","./src/components/doctree.tsx","./src/components/blueprint/blueprintpage.tsx","./src/components/blueprint/detailpanel.tsx","./src/components/blueprint/scene3d.tsx","./src/components/blueprint/systemstructure.tsx","./src/data/sampledata.ts","./src/lib/parser.ts","./src/lib/types.ts","./src/store/blueprintstore.ts"],"version":"5.9.3"} \ No newline at end of file +{"root":["./src/app.tsx","./src/config.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/apidocviewer.tsx","./src/components/doccontent.tsx","./src/components/doctree.tsx","./src/components/blueprint/blueprintpage.tsx","./src/components/blueprint/detailpanel.tsx","./src/components/blueprint/scene3d.tsx","./src/components/blueprint/systemstructure.tsx","./src/data/blueprintparser.ts","./src/lib/parser.ts","./src/lib/types.ts","./src/store/blueprintstore.ts"],"version":"5.9.3"} \ No newline at end of file