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