Repository navigation
Selection Manager
Centralized editor object selection and picking pipeline with single, multi, marquee, and GPU-based selection modes.
Source: SparkEditor/Source/Panels/SelectionManager.h
The Selection Manager is the single source of truth for which entities are selected in the editor. All panels -- Hierarchy, Inspector, Scene View, Property Grid -- observe selection changes through registered callbacks rather than polling, ensuring consistent state across the entire editor UI.
The system supports multiple selection paradigms: single-click replaces the selection, Ctrl+click adds or toggles individual entities, and marquee (box) selection captures all entities within a screen-space rectangle. GPU picking integrates with an ID render pass where each entity is drawn with a unique color; the clicked pixel's entity ID is fed back through SetPickResult. All selection operations respect the active filter and entity lock state.
Selection groups allow saving and restoring named sets of entities, useful for repeatedly working with the same objects. Entity locking prevents accidental selection of background geometry or locked layers. The callback system uses incrementing IDs so listeners can unregister cleanly.
| Class / Struct | Description |
|---|---|
SelectionManager |
Singleton managing current selection state, marquee, filtering, groups, and callbacks |
SelectionChangedEvent |
Event payload listing added, removed, and current entities |
SelectionFilter |
Enum of preset filters: All, StaticMeshOnly, LightsOnly, CamerasOnly, PhysicsOnly, AIOnly, Custom |
MarqueeRect |
Screen-space rectangle with normalized bounds and point containment test |
SelectionGroup |
Named collection of entity IDs for save/restore |
ScreenPosition |
2D screen coordinate for entity picking |
auto& sel = SparkEditor::SelectionManager::GetInstance();
sel.Initialize();
// Listen for selection changes (e.g., from Inspector panel)
auto cbId = sel.OnSelectionChanged([](const SparkEditor::SelectionChangedEvent& e) {
for (auto id : e.added)
RefreshInspector(id);
});
// Single select
sel.Select(entityId);
// Multi-select (Ctrl+Click)
sel.AddToSelection(entity2);
sel.ToggleSelection(entity3);
// Marquee selection (mouse drag in scene view)
sel.BeginMarquee(mouseStartX, mouseStartY);
sel.UpdateMarquee(mouseCurX, mouseCurY);
sel.EndMarquee(visibleEntityScreenPositions, /*additive=*/false);
// GPU picking from ID render pass
sel.SetPickResult(entityAtPixel, /*additive=*/holdingCtrl);
// Filter to lights only
sel.SetFilter(SparkEditor::SelectionFilter::LightsOnly);
// Lock background geometry
sel.LockEntity(groundPlaneId);
// Save/restore selection groups
sel.SaveSelectionGroup("BuildingInterior");
sel.RestoreSelectionGroup("BuildingInterior");
// Cleanup
sel.RemoveCallback(cbId);| Method | Return | Description |
|---|---|---|
Select(entityId) |
void |
Select a single entity, clearing previous selection |
AddToSelection(entityId) |
void |
Add an entity to the current selection |
RemoveFromSelection(entityId) |
void |
Remove an entity from the selection |
ToggleSelection(entityId) |
void |
Toggle an entity's selected state |
ClearSelection() |
void |
Deselect all entities |
SelectMultiple(entities) |
void |
Replace selection with a list of entities |
| Method | Return | Description |
|---|---|---|
IsSelected(entityId) |
bool |
Check if an entity is currently selected |
GetSelectionCount() |
size_t |
Number of selected entities |
GetSelection() |
const vector<EntityId>& |
Ordered list of selected entity IDs |
GetPrimarySelection() |
EntityId |
The most recently clicked entity |
HasSelection() |
bool |
Whether anything is selected |
| Method | Return | Description |
|---|---|---|
BeginMarquee(x, y) |
void |
Start a marquee rectangle at screen position |
UpdateMarquee(x, y) |
void |
Update the marquee corner as the mouse moves |
EndMarquee(positions, additive) |
void |
Finalize marquee and select contained entities |
SetPickResult(entityId, additive) |
void |
Feed GPU pick result into the selection system |
| Method | Return | Description |
|---|---|---|
SetFilter(filter) |
void |
Set a selection filter preset |
SetCustomFilter(callback) |
void |
Set a custom filter function |
ClearFilter() |
void |
Remove all filters |
LockEntity(id) |
void |
Prevent an entity from being selected |
UnlockEntity(id) |
void |
Allow a locked entity to be selected again |
| Method | Return | Description |
|---|---|---|
SaveSelectionGroup(name) |
void |
Save current selection as a named group |
RestoreSelectionGroup(name) |
void |
Restore a saved selection group |
DeleteSelectionGroup(name) |
void |
Delete a named group |
OnSelectionChanged(callback) |
uint32_t |
Register a change listener, returns callback ID |
RemoveCallback(callbackId) |
void |
Unregister a change listener |
- Editor Panels -- all panels observe selection via callbacks
- Scene Hierarchy -- tree view drives and reflects selection
- Inspector Panel -- displays properties of selected entities
- Editor Automation -- automation commands can manipulate selection
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers