feat: load 3D blueprint from MD file instead of hardcoded data
This commit is contained in:
@@ -69,7 +69,7 @@ export default function DetailPanel() {
|
||||
</div>
|
||||
|
||||
{subsystem.depends_on.length > 0 && (
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<div className="text-[10px] font-medium text-zinc-500 uppercase tracking-wider mb-2">Depends On</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{subsystem.depends_on.map((d, i) => (
|
||||
@@ -78,6 +78,31 @@ export default function DetailPanel() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{subsystem.boundary && (
|
||||
<div>
|
||||
{subsystem.boundary.inputs.length > 0 && (
|
||||
<div className="mb-3">
|
||||
<div className="text-[10px] font-medium text-zinc-500 uppercase tracking-wider mb-2">Inputs</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{subsystem.boundary.inputs.map((input, i) => (
|
||||
<span key={i} className="px-1.5 py-0.5 bg-zinc-700/50 text-zinc-300 text-[10px]">{input}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{subsystem.boundary.outputs.length > 0 && (
|
||||
<div>
|
||||
<div className="text-[10px] font-medium text-zinc-500 uppercase tracking-wider mb-2">Outputs</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{subsystem.boundary.outputs.map((output, i) => (
|
||||
<span key={i} className="px-1.5 py-0.5 bg-zinc-700/50 text-zinc-300 text-[10px]">{output}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -105,7 +130,7 @@ export default function DetailPanel() {
|
||||
params: {api.params.map(p => p.name).join(', ') || 'none'}
|
||||
</div>
|
||||
<div className="text-[10px] text-zinc-600">
|
||||
returns: {api.returns.type}
|
||||
returns: {api.returns?.type || 'void'}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
231
src/data/blueprintParser.ts
Normal file
231
src/data/blueprintParser.ts
Normal file
@@ -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<Subsystem> | 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<Module> | 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);
|
||||
@@ -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' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
804
src/docs/blueprint.md
Normal file
804
src/docs/blueprint.md
Normal file
@@ -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: [...]
|
||||
```
|
||||
@@ -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<BlueprintStore>((set) => ({
|
||||
blueprint: sampleBlueprint,
|
||||
blueprint: blueprintData,
|
||||
selectedNode: null,
|
||||
setSelectedNode: (id) => set({ selectedNode: id }),
|
||||
}));
|
||||
|
||||
@@ -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"}
|
||||
{"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"}
|
||||
Reference in New Issue
Block a user