- ADT doodad/WMO positions now converted from ADT space to render coords
via core::coords::adtToWorld() — fixes objects appearing at wrong positions
when loading existing WoW maps
- Selecting a map in the Load dialog now auto-finds the first valid tile
(no more clicking "Find Tile" manually — it's automatic)
- Better error messages with toast for failed terrain loads
- Validates mesh has valid chunks before attempting GPU upload
Root cause of ADT loading failures: instanced maps (dungeons, raids)
have arbitrary internal coord values (e.g. tile 62,0 for a file named
_28_27.adt). The terrain mesh generator uses these coords to compute
world positions, resulting in chunks placed thousands of units away
from the camera → "Failed to upload terrain to GPU".
Fix: override terrain_.coord with the tileX/tileY from the filename
before mesh generation. This ensures chunks are positioned correctly
regardless of what the ADT file's internal header says.
- Quick Biome Paint: select a biome (Grassland/Forest/Desert/Snow/Swamp/Barrens)
and apply its full texture set in one click
- Sets base texture for all chunks + scatters variation patches
- Each biome has a primary ground texture + secondary variation
- Much faster than manual painting for initial zone texturing
- Scatter Patches: randomly places texture circles across the terrain
for natural-looking surface variation (dirt patches, rock outcrops)
- Configurable count, min/max radius, and seed
- Preset buttons for dirt and rock patches
- Uses the existing paint() method with random positions
- Adds visual variety to otherwise uniform terrain texturing
- Rotate 90 CW button in Mirror/Rotate section
- Snapshots outer vertex heights into 129x129 grid, rotates in-place,
writes back with inner vertices averaged from surrounding outers
- Useful for reorienting terrain features or creating rotational
symmetry (rotate + mirror for 4-way symmetric arenas)
- Gradient Blend: smoothly transitions base texture from one biome
to another across the entire tile (horizontal or vertical)
- Preset buttons: Grass→Sand and Grass→Snow gradients
- Creates natural biome transition zones without manual painting
- Alpha blending from 0% to 100% across 16 chunks
- Detail Noise: adds high-frequency roughness to existing terrain
without destroying the overall shape (amplitude 0.5-10, freq 0.01-0.5)
- Useful after smooth/generate to break up unnaturally smooth surfaces
- Workflow: generate → smooth → detail noise for natural look
- Separate seed from main noise generator for independent control
- paintAlongPath(): paints a texture along a line segment with
configurable width and quadratic edge falloff
- Road mode now automatically applies Elwynn cobblestone texture
when flattening a road path (flatten + texture in one operation)
- Quick distance check skips chunks far from the path for performance
- Alpha blending uses max() so overlapping paths don't wash out
- Edge Ramp: smoothly transitions tile borders to a target height
so adjacent tiles can connect seamlessly
- Configurable target height and ramp width (how far in from the edge)
- Quadratic blend for smooth start from edge → interior
- Essential for multi-tile zone creation: ramp each tile's edges to
match its neighbor's border height
- Smooth Beaches button in Water panel: creates gentle beach slopes
near water level by blending terrain toward waterline height
- Configurable beach width (15 units default)
- Quadratic falloff creates natural concave beach profile
- Use after filling water to soften harsh land-water edges
- Workflow: sculpt → fill water → smooth beaches → paint sand
- Voronoi noise generator: creates cell-like terrain patterns with
ridge features at cell boundaries (F2-F1 distance field)
- Configurable cell count (5-100) and amplitude
- Toggle between Value noise and Voronoi in the noise generator section
- Creates interesting mesa/plateau formations and organic shapes
- Random cell centers with per-cell height variation
- Offset Heights: shifts all terrain heights by a constant amount
(-100 to +100 range with Apply button)
- Useful for raising terrain above water level or sinking below
- Slider + Apply button in the Noise Generator section
- Invert Heights: flips terrain upside-down around midpoint (mountains
become valleys and vice versa)
- Fill Entire Tile with Water: one-click fills all 256 chunks at the
configured water height and liquid type
- Remove ALL Water: clears water from every chunk instantly
- Water panel now has three water operations: fill tile, remove under
brush, remove all
- fillWater() and invertHeights() methods on TerrainEditor
- Canyon Generator: carves a winding canyon across the entire tile
using layered sine waves for natural serpentine shape
- Configurable width, depth, and seed for different canyon shapes
- Quadratic falloff at edges for smooth cliff walls
- Random seed button for quick shape exploration
- Fill with Water mode for instant river canyon
- Island Generator: creates raised center terrain dropping to edges
with configurable center height and edge drop depth
- Flat interior plateau → gradual beach slope → steep underwater drop
- Preserves existing noise detail at 30% blend for natural variation
- Add water around the island for instant ocean environment
- Workflow: New Terrain → Island → Noise → Smooth → Auto-paint
- File > Generate Complete Zone: runs the full procedural pipeline
in one click: noise → smooth (3 passes) → recalc normals →
height-based auto-paint (sand/grass/rock/snow) → slope-based
cliff paint (rock on steep faces)
- Creates a fully textured, natural-looking zone from flat terrain
- Removed stale quickGenerate checkbox from New Terrain dialog
- Auto-Paint by Slope: paints rock texture on steep terrain surfaces
with configurable slope threshold (0.1 - 0.9)
- Uses per-vertex normal Z component to detect steepness
- Alpha blending based on slope gradient for smooth transitions
- Workflow: sculpt terrain → recalc normals → auto-paint slope → rock
appears naturally on cliffs while flat areas keep their biome texture
- Creature names rendered as screen-space text above each NPC marker
- Red text for hostile, green for friendly
- Labels project from 3D world position to screen coordinates
- Only visible when NPC is in front of camera (clip.w > 0)
- Much easier to identify placed creatures at a glance
- NPC placement now only updates cheap marker geometry (no M2 reload)
- Full M2 rebuild only triggers when PLACED OBJECT count changes
(not NPC count — NPCs use markers, not M2 instances for now)
- Split lastObjectCount_ into lastObjCount_ + lastNpcCount_ to track
objects and NPCs independently
- Prevents the destructive clear+reload cycle that caused GPU crashes
when rapidly placing multiple NPCs
- Filter known effect/particle models from NPC presets (alliancebomb,
blackhole, etc.) that cause vertex explosions — these are particle
effect models misclassified as creatures
- "Find Tile" button now shows toast when no ADT exists for a map
- Vertex validation catches NaN/infinite/extreme positions before GPU
- These models are now skipped entirely from the creature browser
Root cause of GPU crashes (VK_ERROR_DEVICE_LOST): every NPC placement
triggered a full clear+reload of ALL M2 models. After several cycles
the GPU state corrupted, causing vertex explosions and device lost.
Fixes:
- NPC placement now only updates cheap marker geometry (no M2 reload)
- Full M2 rebuild only happens when object COUNT changes (not every click)
- clearAllObjects() properly resets viewport, placer, spawner, markers,
and history in one call with vkDeviceWaitIdle fence
- New Terrain uses clearAllObjects() for consistent reset
- Clear All menu item calls clearAllObjects()
- M2 vertex validation: rejects models with NaN/infinite/extreme
vertex positions before GPU upload (prevents vertex explosions)
- NPC marker building extracted to updateNpcMarkers() method
(can be called independently without M2 rebuild)