Add scene graph draft

This commit is contained in:
2026-01-25 22:06:58 +09:00
parent fdf831630b
commit 49f54c6b43
18 changed files with 1632 additions and 1553 deletions

View File

@@ -0,0 +1,182 @@
# Scene Graph System Implementation Summary
All planned features from the `SceneGraph Plan.md` have been implemented successfully. Here's what was created:
## 1. Runtime Types (Ghost.Engine)
### Scene.cs
- **Scene struct**: Lightweight runtime identifier for scenes
- **SceneManager class**: Manages scene lifecycle in a world
- `CreateScene()`: Creates new scenes
- `UnloadScene()`: Destroys all entities in a scene
- `GetSceneEntities()`: Queries entities by scene ID
Key design: Minimal runtime footprint, no metadata stored.
## 2. Editor Data Structures (Ghost.Editor.Core)
### SceneNode.cs
- Editor-only scene representation
- Properties:
- `Name`: Display name (NOT in runtime)
- `FilePath`: Where scene is saved
- `IsLoaded`, `IsDirty`: Editor state tracking
- `RootEntities`: Observable collection of root entity nodes
- Methods for managing root entities and finding nodes
### EntityNode.cs
- Editor-only entity representation
- Properties:
- `Name`: Display name (NOT in runtime)
- `Parent`, `Children`: Editor hierarchy
- `OwnerScene`: Back-reference to scene
- Methods for hierarchy management (AddChild, RemoveChild, FindNode, GetAllDescendants)
Both classes use `ObservableCollection` for WinUI 3 TreeView binding support.
## 3. Editor World Management
### EditorWorldManager.cs
- Central manager for editor world and scene graph
- Features:
- Scene creation/unloading
- Entity creation/destruction with automatic SceneID assignment
- Hierarchy component management
- Entity/Scene node tracking via dictionaries
- `RebuildSceneGraph()`: Reconstructs scene graph from world state after loading
Maintains bidirectional mapping: Entity ↔ EntityNode, SceneID ↔ SceneNode
## 4. Serialization (Ghost.Editor.Core)
### SceneData.cs
JSON data structures:
- `SceneData`: Contains name + list of entities
- `EntityData`: Name, parent local ID, components dictionary
- `ComponentData`: Type name + fields dictionary
**Key Feature**: Entities are ordered by file-local ID (index in list).
### SceneSerializer.cs
Complete save/load implementation with entity reference remapping:
**Save Process**:
1. Build `Entity → FileLocalID` mapping
2. Serialize each entity's components
3. **Entity references converted to file-local IDs**
4. Validate no cross-scene references (throws exception if found)
5. Write JSON to file
**Load Process**:
1. Read JSON
2. Create all entities first (two-pass)
3. Build `FileLocalID → Entity` mapping
4. Deserialize components, **remapping file-local IDs back to global Entity IDs**
5. Rebuild hierarchy
Uses reflection to serialize/deserialize component fields. Entity references are detected by field type and specially handled.
## 5. Hierarchy System (Ghost.Engine)
### HierarchyUtility.cs
Runtime utilities for working with Hierarchy component:
- `SetParent()`: Update parent-child relationships, maintains sibling lists
- `GetParent()`: Query parent
- `GetChildren()`: Get immediate children
- `GetDescendants()`: Recursive depth-first traversal
- `IsAncestor()`: Check ancestor relationship
Uses the existing `Hierarchy` component (parent, firstChild, nextSibling pattern).
## 6. Validation (Ghost.Editor.Core)
### SceneValidator.cs
Validates scene integrity:
**ValidateSceneReferences**:
- Checks all Entity fields in components
- Ensures referenced entities exist
- **Enforces same-scene constraint** (errors on cross-scene refs)
**ValidateHierarchy**:
- Detects circular parent-child loops
- Warns if parent is outside scene
Returns `ValidationResult` with errors/warnings lists.
## Architecture Highlights
### Runtime vs Editor Separation
- Runtime (`Ghost.Engine`): Only SceneID component, SceneManager, HierarchyUtility
- Editor (`Ghost.Editor.Core`): All metadata (names), scene graph tree, serialization
- **Zero runtime overhead** for editor-only data
### Entity Reference Remapping
Per plan, entity references use **file-local IDs** in saved scenes:
- Avoids brittle global IDs
- Enables scene prefabs/templates in future
- Automatically remapped on load
### Cross-Scene Reference Prevention
- Validation layer enforces no cross-references
- SerializeComponent throws exception if detected during save
- Plan notes: Use queries/singletons for cross-scene access
### JSON for Editor, Binary for Runtime
- Current impl: JSON serialization for editor (SceneSerializer.cs)
- Plan notes MemoryPack for runtime binary format
- Reflection allowed in editor, AOT-compatible runtime preserved
## Integration Points
### Existing Components Used
- `SceneID` (Ghost.Engine/Components/SceneID.cs) - scene membership tag
- `Hierarchy` (Ghost.Engine/Components/Hierarchy.cs) - parent-child structure
- `LocalToWorld` - transform (referenced but not modified)
### ECS Integration
- Uses `QueryBuilder` and chunk iteration for queries
- `EntityManager` for all entity operations
- Archetype layouts for component enumeration
## What's NOT Implemented (As Per Plan)
The plan explicitly states:
> "Leave the actual UI implementation (TreeView) for later"
Not included in this implementation:
- WinUI 3 TreeView XAML
- UI controls for hierarchy panel
- Drag-drop entity reparenting
- Context menus
- Icons/gizmos
These are left for UI layer implementation. The data structures (SceneNode, EntityNode with ObservableCollection) are designed to bind directly to TreeView.
## Files Created
**Ghost.Engine:**
- `Scene.cs` - Scene struct + SceneManager
- `Systems/HierarchyUtility.cs` - Hierarchy helpers
**Ghost.Editor.Core:**
- `SceneGraph/SceneNode.cs` - Scene graph node
- `SceneGraph/EntityNode.cs` - Entity graph node
- `SceneGraph/EditorWorldManager.cs` - Central manager
- `Serialization/SceneData.cs` - JSON data structures
- `Serialization/SceneSerializer.cs` - Save/load logic
- `Validation/SceneValidator.cs` - Integrity checks
Total: 7 new files, ~1400 lines of code
## Next Steps
To complete the scene graph feature:
1. **Create WinUI 3 TreeView** bound to `EditorWorldManager.LoadedScenes`
2. **Add toolbar**: New Scene, Save Scene, Unload Scene buttons
3. **Entity creation UI**: Right-click menu, "Create Empty" button
4. **Drag-drop**: Reparent entities by dragging in TreeView
5. **Rename**: Double-click to rename EntityNode.Name
6. **Integration**: Wire EditorWorldManager into main editor app lifecycle
All the core logic is complete and follows the plan precisely.