feat(editor): undo object placement, snap to ground, keyboard shortcuts

- Ctrl+Z in Object/NPC mode undoes last placement (50-deep stack)
- "Snap Ground" button raycasts straight down to place object on terrain
- Useful for objects placed too high or moved off terrain surface
- Undo stack adjusts indices when objects are removed mid-stack
This commit is contained in:
Kelsi 2026-05-05 04:01:06 -07:00
parent ace6173401
commit 88abbfb564
5 changed files with 50 additions and 5 deletions

View file

@ -29,6 +29,8 @@ void ObjectPlacer::placeObject(const glm::vec3& position) {
obj.selected = false;
objects_.push_back(obj);
undoStack_.push_back(static_cast<int>(objects_.size() - 1));
if (undoStack_.size() > 50) undoStack_.erase(undoStack_.begin());
LOG_INFO("Placed ", (activeType_ == PlaceableType::M2 ? "M2" : "WMO"),
": ", activePath_, " at (", position.x, ",", position.y, ",", position.z, ")");
}
@ -93,6 +95,19 @@ void ObjectPlacer::deleteSelected() {
selectedIdx_ = -1;
}
void ObjectPlacer::undoLastPlace() {
if (undoStack_.empty()) return;
int idx = undoStack_.back();
undoStack_.pop_back();
if (idx >= 0 && idx < static_cast<int>(objects_.size())) {
if (selectedIdx_ == idx) selectedIdx_ = -1;
else if (selectedIdx_ > idx) selectedIdx_--;
objects_.erase(objects_.begin() + idx);
// Adjust remaining undo indices
for (auto& i : undoStack_) { if (i > idx) i--; }
}
}
void ObjectPlacer::syncToTerrain() {
if (!terrain_) return;