115 lines
5.4 KiB
Markdown
115 lines
5.4 KiB
Markdown
## Context
|
|
|
|
The application currently has a `SceneHierarchyPanel` class (92 lines) that implements a functional tree view of USD prims:
|
|
- Uses `PropertyManager::GetPrimPaths()` to get all prims
|
|
- Recursively renders prims with `RenderPrimNode()` showing name, type, and selection state
|
|
- Supports selection highlighting, tooltips with type/path, and double-click/arrow expansion
|
|
- Has a callback mechanism (`PrimSelectCallback`) for notifying when a prim is selected
|
|
|
|
However, `Application::RenderUI()` (lines 94-103) ignores this class and renders an inline placeholder instead:
|
|
```cpp
|
|
ImGui::Begin("Scene Hierarchy", nullptr, ImGuiWindowFlags_NoCollapse);
|
|
if (m_stageManager->HasStage()) {
|
|
ImGui::Text("Stage loaded: %s", m_stageManager->GetRootLayerIdentifier().c_str());
|
|
ImGui::Separator();
|
|
ImGui::Text("Scene hierarchy will be displayed here");
|
|
} else {
|
|
ImGui::TextDisabled("No stage loaded");
|
|
ImGui::Text("Open a USD file to view scene hierarchy");
|
|
}
|
|
ImGui::End();
|
|
```
|
|
|
|
Meanwhile, the `LayerPanel` class is properly wired in (lines 105-111) and functions correctly:
|
|
```cpp
|
|
ImGui::Begin("Layer Panel", nullptr, ImGuiWindowFlags_NoCollapse);
|
|
if (m_stageManager->HasStage()) {
|
|
m_layerPanel->Render();
|
|
} else {
|
|
ImGui::TextDisabled("No stage loaded");
|
|
}
|
|
ImGui::End();
|
|
```
|
|
|
|
The `PropertyPanel` class exists as a header only (no .cpp file) and is also rendered as a placeholder.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
- Wire the existing `SceneHierarchyPanel` into `Application` so it functions as a dockable panel
|
|
- Enhance the panel with prim type icons, visibility/active state indicators, and context menus
|
|
- Ensure prim selection drives other panels (Property Panel) via the existing callback mechanism
|
|
- Maintain consistency with the existing `LayerPanel` wiring pattern
|
|
|
|
**Non-Goals:**
|
|
- Do not create a new panel class from scratch (the class already exists)
|
|
- Do not modify the core USD traversal logic in `PropertyManager` (it's already functional)
|
|
- Do not implement 3D viewport or property editing in this change
|
|
- Do not change the docking architecture or ImGui context management
|
|
|
|
## Decisions
|
|
|
|
### 1. Wiring Pattern: Follow Existing LayerPanel Approach
|
|
**Decision:** Wire `SceneHierarchyPanel` exactly like `LayerPanel` - create instance in `Application::Initialize()`, call `SetPropertyManager()`, and invoke `Render()` in `Application::RenderUI()`.
|
|
|
|
**Rationale:**
|
|
- Consistency with existing working pattern (`LayerPanel`)
|
|
- Minimal changes required
|
|
- Clear separation of concerns (Application manages lifecycle, panel handles rendering)
|
|
- Avoids duplicating the placeholder code
|
|
|
|
**Alternatives Considered:**
|
|
- Inline rendering in Application (current placeholder) - rejected because it duplicates existing functionality
|
|
- Creating panel on-demand in RenderUI - rejected because it loses state and breaks consistency
|
|
|
|
### 2. Enhancement: Add Visual Indicators for Prim State
|
|
**Decision:** Enhance `SceneHierarchyPanel::RenderPrimNode()` to show:
|
|
- Prim type icons (using Unicode characters or colored text)
|
|
- Visibility/inactive state indicators (eye icon or strike-through)
|
|
- Reference/instance indicators
|
|
- Context menu for common operations (toggle visibility, toggle active)
|
|
|
|
**Rationale:**
|
|
- Provides immediate visual feedback about prim state without opening property panel
|
|
- Matches user expectations from similar tools (Maya Outliner, Unity Hierarchy)
|
|
- Leverages existing USD API (`GetVisibility()`, `GetActive()`)
|
|
- Non-invasive enhancement that builds on solid foundation
|
|
|
|
**Implementation Notes:**
|
|
- Use `prim.GetVisibility()` and `prim.GetActive()` to determine state
|
|
- Show icons before prim name: 👁️ (visible), 👁️🗨️ (invisible), ○ (active), ● (inactive)
|
|
- Context menu via `ImGui::BeginPopupContextItem()` on the tree node
|
|
|
|
### 3. Integration: Connect Selection to Property Panel
|
|
**Decision:** Implement the `PrimSelectCallback` in `Application` to update the `PropertyPanel` when selection changes (once PropertyPanel is implemented).
|
|
|
|
**Rationale:**
|
|
- Leverages existing callback mechanism in SceneHierarchyPanel
|
|
- Enables future integration with PropertyPanel
|
|
- Follows event-driven pattern already established
|
|
- No changes needed to SceneHierarchyPanel itself
|
|
|
|
**Note:** PropertyPanel currently doesn't exist as .cpp, so this sets up the foundation for when it's implemented.
|
|
|
|
### 4. Performance: Maintain Existing Traversal Approach
|
|
**Decision:** Keep the existing `PropertyManager::GetPrimPaths()` + recursive traversal approach.
|
|
|
|
**Rationale:**
|
|
- Already implemented and working
|
|
- `GetPrimPaths()` uses efficient `UsdPrimRange` traversal
|
|
- Caching isn't needed for typical scene sizes (<10k prims)
|
|
- Premature optimization would complicate the clean implementation
|
|
|
|
## Risks / Trade-offs
|
|
|
|
[Performance] → Acceptable for typical USD scenes; `GetPrimPaths()` is O(N) but only called when stage changes or panel refreshes needed.
|
|
|
|
[UI Clutter] → Added icons and context menus enhance usability without overwhelming the interface; users can ignore extra visual cues if not needed.
|
|
|
|
[Tight Coupling] → Application now depends on SceneHierarchyPanel class; however, this follows the same pattern as LayerPanel and is acceptable for core UI components.
|
|
|
|
[Missing PropertyPanel] → Selection callback won't have immediate effect until PropertyPanel is implemented; this is expected and sets up proper integration for future work.
|
|
|
|
## Open Questions
|
|
|
|
None - the path forward is clear: wire the existing panel, enhance it with visual indicators, and maintain consistency with existing patterns. |