fix(editor): crater button now click-to-place on terrain

The "Create Crater at Cursor" button used the brush's last hover
position, which was stale by the time the user clicked the button —
the cursor had to move onto the button itself, dragging the brush
position along with it. Result: crater spawned somewhere between
where the user wanted and the button.

New flow: button arms a "click on terrain to place crater" mode
(captures the user's chosen radius/depth/rim at arm time). The next
left-click anywhere on terrain spawns the crater at the actual click
position, regardless of brush state. Button label changes to "ARMED
— click on terrain to place" while waiting, with a Cancel button +
Esc to dismiss.

Misses on terrain leave the mode armed so the user can retry without
re-pressing the button.
This commit is contained in:
Kelsi 2026-05-07 09:34:17 -07:00
parent b35c9341ec
commit 0e2b55f9fd
3 changed files with 64 additions and 4 deletions

View file

@ -351,6 +351,10 @@ void EditorApp::processEvents() {
objectPlacer_.clearSelection();
npcSpawner_.clearSelection();
ui_.clearPath();
if (pendingCrater_.active) {
pendingCrater_.active = false;
showToast("Crater placement cancelled");
}
}
}
if (sc == SDL_SCANCODE_DELETE) {
@ -531,6 +535,31 @@ void EditorApp::processEvents() {
giz.endDrag();
giz.setMode(TransformMode::None);
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
// Pending crater placement: take precedence over the
// mode-based click handling below so the next click
// anywhere on terrain spawns the crater instead of
// doing whatever the current mode does.
if (pendingCrater_.active) {
auto ext = window_->getVkContext()->getSwapchainExtent();
rendering::Ray ray = camera_.getCamera().screenToWorldRay(
static_cast<float>(event.button.x),
static_cast<float>(event.button.y),
static_cast<float>(ext.width),
static_cast<float>(ext.height));
glm::vec3 hitPos;
if (terrainEditor_.raycastTerrain(ray, hitPos)) {
terrainEditor_.createCrater(hitPos,
pendingCrater_.radius,
pendingCrater_.depth,
pendingCrater_.rim);
showToast("Crater placed");
pendingCrater_.active = false;
}
// If the click missed terrain, leave the mode armed
// so the user can try again without re-pressing the
// button.
continue;
}
// Path point capture (river/road tool)
// Alt+click eyedropper in paint mode
if (mode_ == EditorMode::Paint && (SDL_GetModState() & KMOD_ALT)) {