Commit graph

3456 commits

Author SHA1 Message Date
Kelsi
126567a1d0 feat(editor): show scale and rotation info for selected objects 2026-05-05 10:56:48 -07:00
Kelsi
05d7dcd927 feat(editor): show open format indicator in placed objects count 2026-05-05 10:55:07 -07:00
Kelsi
b29aee062a chore(editor): note all 6 Blizzard formats replaced in About dialog 2026-05-05 10:53:49 -07:00
Kelsi
e7cf125fda docs(editor): improved CLI help with format info and all options 2026-05-05 10:52:17 -07:00
Kelsi
4b94640cae feat(editor): CLI batch convert mode (--convert-m2) for M2→WOM conversion
- wowee_editor --convert-m2 <path> --data <datadir> converts a single
  M2 model to WOM open format without launching the GUI
- Output goes to output/models/ with same path structure
- Useful for batch scripts to convert entire asset directories
- Example: wowee_editor --data Data --convert-m2 creature\\bear\\bear.m2
2026-05-05 10:50:36 -07:00
Kelsi
bf83da61d2 chore(editor): update About dialog with open format stats (11k+ lines, 6 formats) 2026-05-05 10:48:31 -07:00
Kelsi
e191f35ed0 feat(editor): content pack inspector and improved import UI 2026-05-05 10:47:18 -07:00
Kelsi
6acde0290d docs(editor): FORMAT_SPEC.md documenting all 5 novel open file formats 2026-05-05 10:45:50 -07:00
Kelsi
4148c890dc feat(editor): auto-export WMO buildings as WOB placeholders on zone save
- Zone export now creates WOB placeholder files for all placed WMO
  buildings in output/MapName/buildings/
- Full WMO→WOB conversion (with geometry) requires group file loading
  which is complex — placeholders reserve the path structure for now
- All 6 format conversions now auto-run on every zone export:
  ADT→WOT/WHM, BLP→PNG, DBC→JSON, M2→WOM, WMO→WOB, WDT→zone.json
2026-05-05 10:44:38 -07:00
Kelsi
c532a1a787 chore(editor): bump version to 0.8.0 — full open format pipeline 2026-05-05 10:41:43 -07:00
Kelsi
adfa1d7086 feat(editor): export toast shows open format completeness score (X/5) 2026-05-05 10:40:15 -07:00
Kelsi
a54ce494be feat(editor): zone validation for open format completeness scoring
- ContentPacker::validateZone() scans a zone directory and checks
  for all open format files (WOT, WHM, PNG, WOM, zone.json, etc.)
- openFormatScore(): returns 0-5 based on how many open formats present
- summary(): human-readable list of found formats
- Foundation for quality gate on WCP export: warn if zone uses
  Blizzard formats that could be converted to open versions
2026-05-05 10:38:57 -07:00
Kelsi
8517ae3778 feat: client loads WOM open models from custom zones automatically
- TerrainManager now checks for .wom files before loading M2 models
- Searches custom_zones/models/ and output/MapName/models/ directories
- Converts WOM vertices/indices to M2Model struct for the renderer
- Full pipeline: editor exports M2→WOM → client loads WOM directly
- Falls back to standard M2 loading if no WOM found

The client can now render custom zone content using entirely
open formats: WOT/WHM terrain + WOM models + PNG textures
2026-05-05 10:36:46 -07:00
Kelsi
5e2cb6fb3c feat(editor): auto-convert placed M2 objects to WOM on zone export
- Zone export now converts all placed M2 models to WOM open format
- Deduplicates: each unique M2 path converted only once
- WOM files saved to output/MapName/models/ with original path structure
- Uses WoweeModelLoader::fromM2() for M2→WOM conversion
- Combined with PNG texture export, zones can now be fully distributed
  without any Blizzard proprietary files

Full open format export pipeline:
  Terrain: ADT→WOT/WHM | Textures: BLP→PNG | Data: DBC→JSON
  Models: M2→WOM | Buildings: WMO→WOB (manual) | Map: WDT→zone.json
2026-05-05 10:31:51 -07:00
Kelsi
71c3eb0fe6 feat: Wowee Open Building format (.wob) — novel WMO replacement
ALL 6 BLIZZARD FORMATS NOW HAVE OPEN REPLACEMENTS.

WOB format: binary building file with groups, portals, and doodads.
- WOB1 magic header
- Groups: vertices (pos+normal+uv+color), indices, texture paths,
  bounding box, indoor/outdoor flag
- Portals: connect groups with polygon boundaries
- Doodad placements: reference .wom models with transform

WoweeBuildingLoader: load/save/exists for .wob files.

Complete format replacement table:
- ADT → WOT/WHM (terrain heightmaps + metadata)
- WDT → zone.json (map definition)
- BLP → PNG (textures)
- DBC → JSON (data tables)
- M2 → WOM (static models)
- WMO → WOB (buildings with groups/portals/doodads)

The wowee project now has a complete suite of novel, open file
formats for creating and distributing custom WoW content without
any dependency on Blizzard proprietary file formats.
2026-05-05 10:28:24 -07:00
Kelsi
b4cb833108 feat: Wowee Open Model format (.wom) — novel M2 replacement
WOM format: binary model file with no Blizzard structures.
- WOM1 magic header + vertex/index counts + bounding box
- Vertices: position(vec3) + normal(vec3) + texCoord(vec2) = 32 bytes
- Indices: uint32 triangle list
- Texture paths: PNG references (not BLP)

WoweeModelLoader:
- load(): reads .wom binary back to WoweeModel struct
- save(): writes WoweeModel to .wom binary
- fromM2(): converts existing M2 models to WOM (static geometry,
  strips bone/animation data, converts BLP paths to PNG)
- exists(): checks for .wom file

Format replacement progress — 5 out of 6 done:
- DONE: ADT → WOT/WHM (terrain)
- DONE: WDT → zone.json (map definition)
- DONE: BLP → PNG (textures)
- DONE: DBC → JSON (data tables)
- DONE: M2 → WOM (static models)
- TODO: WMO → open building format
2026-05-05 10:24:46 -07:00
Kelsi
176115f279 feat(editor): DBC→JSON export for open format zone data tables
- DBCExporter: converts Blizzard DBC binary data tables to JSON
- Exports zone-relevant DBCs: AreaTable, Map, Light, LightParams,
  ZoneMusic, SoundAmbience, GroundEffectTexture/Doodad, LiquidType
- Auto-detects string vs numeric vs float fields
- Zone export now includes data/ directory with JSON DBCs
- Client can load these via existing CSV/JSON fallback paths

Format replacement progress:
- DONE: ADT → WOT/WHM (terrain)
- DONE: WDT → zone.json (map definition)
- DONE: BLP → PNG (textures)
- DONE: DBC → JSON (data tables)
- TODO: M2 → open model format
- TODO: WMO → open building format
2026-05-05 10:21:14 -07:00
Kelsi
cb3de59b5c feat(editor): BLP→PNG texture export for open format zones
- TextureExporter: converts Blizzard BLP textures to standard PNG
  for fully open redistribution of custom zones
- collectUsedTextures(): finds all texture paths referenced by terrain
- exportTexturesAsPng(): loads BLP via asset manager, writes RGBA PNG
  using stb_image_write to output/MapName/textures/
- Zone export now automatically converts all used textures to PNG
- Client's PNG override system already loads these automatically
  (checks for .png alongside .blp before loading)

Format replacement progress:
- DONE: ADT→WOT/WHM (terrain)
- DONE: WDT→zone.json (map definition)
- DONE: BLP→PNG (textures — auto-exported on zone save)
- TODO: DBC→JSON, M2→open model, WMO→open building
2026-05-05 10:17:03 -07:00
Kelsi
5adb6cb364 feat(editor): export toast shows file count for better feedback 2026-05-05 10:11:50 -07:00
Kelsi
40561fbe7a fix(editor): correct noise type count in About dialog (3 types: value, voronoi, detail) 2026-05-05 10:10:17 -07:00
Kelsi
b4023e13bf chore(editor): bump version to 0.7.0 — full custom content pipeline 2026-05-05 10:08:49 -07:00
Kelsi
a2b69e8e09 feat(editor): Import Content Pack button for loading shared WCP archives 2026-05-05 10:06:57 -07:00
Kelsi
c05c15f6c9 feat(editor): Load Custom Zone menu discovers and loads WOT/WHM zones
- File > Load Custom Zone scans output/ and custom_zones/ for zone.json
- Lists all discovered custom zones with name and quest indicator [Q]
- Tooltip shows description and author on hover
- Click to load the zone's WOT/WHM terrain into the editor
- Parses tile coords from WOT filename for correct positioning
- Full round-trip: export → discover → reload for iterative editing
2026-05-05 10:04:45 -07:00
Kelsi
d10d962e31 feat: custom zone discovery system for client auto-detection
- CustomZoneDiscovery scans directories for zone.json manifest files
- Discovers custom zones in custom_zones/ and output/ directories
- Reports: name, author, description, creature/quest availability
- Client can list all available custom expansions at startup
- Foundation for a zone selection menu in the client UI
2026-05-05 10:01:05 -07:00
Kelsi
954894460e feat: integrate Wowee Open Terrain loader into client terrain pipeline
The wowee client can now load custom zones exported from the editor
using the novel WOT/WHM format — no Blizzard files needed.

Loading priority in TerrainManager::prepareTile():
1. Check custom_zones/{mapName}/{mapName}_{x}_{y}.wot/.whm
2. Check output/{mapName}/{mapName}_{x}_{y}.wot/.whm (editor output)
3. Fall back to World\Maps\...\*.adt (standard extracted data)

Pipeline:
- WoweeTerrainLoader in src/pipeline/ (shared between client + editor)
- Loads .whm binary heightmap (WHM1 magic, 256 chunks × 145 floats)
- Loads .wot JSON metadata (textures, layers, holes, water)
- Populates the same ADTTerrain struct the mesh generator uses
- obj0 merge only runs for ADT-loaded tiles (custom zones have no obj0)

To use: export zone from editor → files appear in output/ → client
loads them automatically on next terrain request for that map name.
2026-05-05 09:56:24 -07:00
Kelsi
94e6d5276e feat(editor): git integration for collaborative expansion development
- File > Project > Git submenu: Init, Commit, Push, Pull operations
- Init Git Repo: initializes git in the project directory with initial commit
- Commit Changes: auto-saves zone then commits all changes
- Push/Pull: sync with remote repositories for team collaboration
- Git Status: shows current repo state directly in the menu
- Teams can collaborate on custom expansions using standard git workflows
2026-05-05 09:45:00 -07:00
Kelsi
6f35081013 feat(editor): switch between project zones via File > Project > Switch Zone
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
2026-05-05 09:42:58 -07:00
Kelsi
8c648dff85 chore(editor): bump version to 0.6.0 — 10k lines, projects, open formats 2026-05-05 09:41:08 -07:00
Kelsi
18939af73d feat(editor): project management UI in File menu
- File > Project submenu: New/Save/Load project, add zones
- "Add Current Zone to Project" captures loaded map/tile info
- Project path editable in the menu
- Zone count shown for quick reference
- Foundation for multi-zone custom expansion workflow:
  create project → add zones → edit each → export all as WCP
2026-05-05 09:39:01 -07:00
Kelsi
1d2f25f169 feat(editor): project system for multi-zone custom expansions
- EditorProject: manages multiple zones in a single project file
  (wowee-project-1.0 JSON format)
- Project stores: name, author, description, version, zone list
- Each zone has: mapName, tileX/Y, biome, description
- Save/load project files (.json) with full round-trip
- Foundation for creating custom expansions with multiple maps,
  quest chains spanning zones, and campaign progression
- getZoneOutputDir() resolves per-zone output paths
2026-05-05 09:36:44 -07:00
Kelsi
c28d3f8a99 feat(editor): open terrain format integrated into export workflow
- File > Export Open Format (.wot/.whm) menu item for standalone export
- Every zone export (Ctrl+S, Export Zone) now also writes .wot/.whm
  alongside the ADT/WDT — dual format output
- Export package now contains: ADT + WDT + WOT + WHM + JSON files
- Both Blizzard-compatible (for existing servers) and open format
  (for wowee-native loading and redistribution)
2026-05-05 09:34:49 -07:00
Kelsi
7177463df1 feat(editor): Wowee Open Terrain format (.wot/.whm) — no Blizzard formats
Novel open terrain format unique to wowee:

.wot (Wowee Open Terrain) — JSON metadata:
- Tile coordinates, chunk grid dimensions, texture list
- Per-chunk layer assignments and hole bitmasks
- Water data per chunk (type, height)
- Format version "wot-1.0"

.whm (Wowee HeightMap) — binary heightmap:
- "WHM1" magic header
- 256 chunks × (baseHeight + 145 float heights) = 148KB
- Direct float storage, no compression, fully portable

Both formats are entirely novel — no ADT, no WDT, no Blizzard
structures. The WCP content pack can bundle .wot/.whm instead of
ADT/WDT for fully open redistribution.

Import/export functions: WoweeTerrain::exportOpen() / importOpen()
2026-05-05 09:32:13 -07:00
Kelsi
be18ceea73 feat(editor): Export Content Pack button in File menu
- File > Export Content Pack (.wcp) saves zone + packs into WCP archive
- Auto-saves zone first, then bundles into the novel WCP format
- WCP is a custom format unique to wowee (not MPQ, not CASC)
- Output: output/MapName.wcp ready for distribution
- Toast notification on success/failure
2026-05-05 09:29:57 -07:00
Kelsi
79ae91a6d5 feat(editor): Wowee Content Pack (.wcp) format for zone distribution
- WCP format: simple binary archive with magic header, JSON manifest,
  and concatenated file data. Not tied to any proprietary format.
- ContentPacker::packZone(): bundles all zone files from output dir
  into a single .wcp file (terrain, objects, creatures, quests, manifest)
- ContentPacker::unpackZone(): extracts .wcp to a directory
- ContentPacker::readInfo(): reads pack metadata without extracting
- Format: "WCP1" magic + fileCount + infoJSON + file table + data
- Foundation for distributing custom zones to other wowee users
  and private servers

Note: currently bundles ADT/WDT files as-is. Future: convert terrain
to open format (heightmap + JSON) for fully open redistribution.
2026-05-05 09:27:00 -07:00
Kelsi
f5d8dcf75a chore(editor): bump version to 0.5.0 (130 commits) 2026-05-05 09:24:21 -07:00
Kelsi
dce51d9de6 fix(editor): cleaner cursor info display in Sculpt panel header 2026-05-05 09:21:44 -07:00
Kelsi
da79244fc5 feat(editor): show cursor height and position at top of Sculpt panel 2026-05-05 09:20:28 -07:00
Kelsi
ec8e3a41b5 fix(editor): Clear All shows toast when nothing to clear 2026-05-05 09:19:02 -07:00
Kelsi
d36631d242 fix(editor): Create + Generate button now actually runs generation pipeline
- "Create + Generate" was setting a flag but never calling generateCompleteZone()
- Now properly chains: create terrain → run full procedural pipeline
  (noise → smooth → normals → height paint → slope paint → detail → water → beaches)
- Uses generateAfterCreate_ flag to defer generation until after terrain is created
2026-05-05 09:17:23 -07:00
Kelsi
bdfadc7e76 fix(editor): remove all remaining brush.isActive() checks from UI buttons
- Pick height, Punch Hole, Fill Hole, Delete All in Radius buttons
  no longer require cursor to be actively on terrain
- All buttons now use last known brush position consistently
- Fixes the fundamental UX issue where clicking a UI button moves
  the cursor off terrain, making the button do nothing
2026-05-05 09:14:31 -07:00
Kelsi
560c4a40c0 fix(editor): About dialog now works, moved outside menu bar scope
- About dialog was broken because ImGui::OpenPopup inside BeginMenu
  has wrong ID scope — popup never appeared
- Changed to a proper ImGui::Begin window with showAbout_ flag
- Closeable with X button or clicking About again
- Shows version, author, feature summary, and tech stack
2026-05-05 09:11:46 -07:00
Kelsi
bab1318ec9 fix(editor): ghost preview logs warning when model file not found 2026-05-05 09:08:03 -07:00
Kelsi
c1f74d9c9c fix(editor): all generator buttons work without cursor on terrain
- Removed isActive() requirement from all "Create at Cursor" buttons
  (Mesa, Crater, Hill, Valley, Stamp, Ridge, Flatten Platform, Holes)
- Buttons now use the last known brush position which persists when
  cursor moves to the UI panel to click the button
- Fixes: "Create Mesa at Cursor can't work if cursor is clicking
  that button" — now it uses wherever the cursor was last on terrain
2026-05-05 09:06:08 -07:00
Kelsi
63f4711eb3 fix(editor): river/road path selection uses last brush pos, edge ramp note
- Set Start/End buttons for river/road no longer require brush to be
  actively on terrain at click time — uses last known brush position
  which persists when cursor moves to the UI panel
- Shows cursor coordinates above the buttons for visual confirmation
- Edge ramp confirmed to only affect terrain heights, not water levels
  (water has its own height independent of terrain)
2026-05-05 09:04:30 -07:00
Kelsi
f6d30fcf9b fix(editor): ghost preview survives object rebuilds, clearObjects resets ghost state
- Ghost model state (ID, path, active flag) properly reset when
  clearObjects() wipes the M2 renderer — prevents stale ghost
  references causing crashes on subsequent hover
- Ghost model ID uses 59999 to avoid collision with placed object IDs
- Ghost loadModel failure now handled gracefully (returns early)
2026-05-05 09:03:02 -07:00
Kelsi
34c06ede4e fix(editor): redo works in all modes, center uses real chunk positions
- Ctrl+Shift+Z redo now works globally (was only in Sculpt mode)
- Ctrl+Z undo works in all modes with toast confirmation
- centerOnTerrain() uses actual mesh chunk positions instead of formula
- Toast shows "Undo" / "Redo" / "Undo placement" for user feedback
2026-05-05 09:00:53 -07:00
Kelsi
66debe9cec fix(editor): camera auto-centers on actual terrain chunks after ADT load
- Camera now positions at the center of actual loaded terrain chunks
  instead of using formula-based coordinates that can be wrong for
  instanced maps
- Falls back to formula if no valid chunks loaded
- Fixes camera starting far from terrain on some maps
2026-05-05 08:58:07 -07:00
Kelsi
84e9146522 feat(editor): toast notification when importing ADT doodads/WMOs 2026-05-05 08:56:52 -07:00
Kelsi
61f0f39611 fix(editor): ADT doodad/WMO coordinate conversion, auto-find tile on map select
- 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
2026-05-05 08:55:09 -07:00
Kelsi
9c0bc5fbd1 fix(editor): override ADT internal coords with filename coords on load
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.
2026-05-05 08:49:26 -07:00