feat(editor): object scatter, camera bookmarks, shortcut hints

- Object scatter tool: place N copies of selected M2/WMO in a radius
  with random rotation and scale range (Min/Max Scale slider)
- Camera bookmarks: F5 saves current position, View > Load Bookmark
  to jump back — useful for working on different parts of a large zone
- Shortcut hints shown at bottom of Object panel
  (G=move, R=rotate, T=scale, Del=remove)
- DragFloatRange2 for min/max scale in scatter UI
This commit is contained in:
Kelsi 2026-05-05 04:20:26 -07:00
parent 48026421c9
commit 5daa359e74
5 changed files with 90 additions and 0 deletions

View file

@ -2,6 +2,7 @@
#include "core/logger.hpp"
#include <algorithm>
#include <cmath>
#include <random>
namespace wowee {
namespace editor {
@ -95,6 +96,34 @@ void ObjectPlacer::deleteSelected() {
selectedIdx_ = -1;
}
void ObjectPlacer::scatter(const glm::vec3& center, float radius, int count,
float minScale, float maxScale) {
if (activePath_.empty()) return;
std::mt19937 rng(static_cast<uint32_t>(center.x * 100 + center.y * 37 + objects_.size()));
std::uniform_real_distribution<float> distAngle(0.0f, 6.2831853f);
std::uniform_real_distribution<float> distDist(0.0f, 1.0f);
std::uniform_real_distribution<float> distRot(0.0f, 360.0f);
std::uniform_real_distribution<float> distScale(minScale, maxScale);
for (int i = 0; i < count; i++) {
float angle = distAngle(rng);
float dist = std::sqrt(distDist(rng)) * radius;
glm::vec3 pos = center + glm::vec3(std::cos(angle) * dist, std::sin(angle) * dist, 0.0f);
PlacedObject obj;
obj.type = activeType_;
obj.path = activePath_;
obj.nameId = 0;
obj.uniqueId = nextUniqueId();
obj.position = pos;
obj.rotation = glm::vec3(0.0f, distRot(rng), 0.0f);
obj.scale = distScale(rng);
obj.selected = false;
objects_.push_back(obj);
}
LOG_INFO("Scattered ", count, " objects in radius ", radius);
}
void ObjectPlacer::undoLastPlace() {
if (undoStack_.empty()) return;
int idx = undoStack_.back();