From 51fd387133fbd9d3fca76c10d48d7c037118e81d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 06:53:24 +0000 Subject: [PATCH] perf(worldbuilder): Skip object refresh while painting terrain tiles Every mouse move of the tile tool refreshed the terrain and then refitted every map object, build list entry, light and scorch to the ground, and flagged all roads and bridges to be rebuilt on the next redraw. Painting textures or pathing never changes heights, so the tile tool now skips that refresh. Full terrain rebuilds and height edits still refresh as before. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01NTMNjbth2DjLNN9Vz87n2v --- .../Code/Tools/WorldBuilder/include/WorldBuilderDoc.h | 2 +- GeneralsMD/Code/Tools/WorldBuilder/include/wbview.h | 5 +++-- GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h | 2 +- GeneralsMD/Code/Tools/WorldBuilder/src/TileTool.cpp | 4 +++- GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp | 4 ++-- GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp | 7 +++++-- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/GeneralsMD/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h b/GeneralsMD/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h index cdc03f01549..8247d786efe 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h +++ b/GeneralsMD/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h @@ -120,7 +120,7 @@ class CWorldBuilderDoc : public CDocument void invalCell(int xIndex, int yIndex); void updateAllViews(); - void updateHeightMap(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange); + void updateHeightMap(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange, Bool invalObjects = true); /// Gets an xy index into the height map from a pixel location. Bool getCellIndexFromCoord(Coord3D pt, CPoint *ndxP); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview.h b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview.h index 38699a0555a..bb4b2e633e7 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview.h +++ b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview.h @@ -110,8 +110,9 @@ class WbView : public CView /// Set the center for display. virtual void setCenterInView(Real x, Real y) { } - /// Update the height map in the 3d window. - virtual void updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange) { } + /// Update the height map in the 3d window. Pass invalObjects=false when no heights changed, + /// so objects, roads, lights and scorches don't need to be refitted to the terrain. + virtual void updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange, Bool invalObjects = true) { } /// the doc has changed size; readjust view as necessary. virtual void adjustDocSize() { } diff --git a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h index 23579a68f04..9262fd299a8 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h +++ b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h @@ -242,7 +242,7 @@ class WbView3d : public WbView, public DX8_CleanupHook virtual Bool viewToDocCoords(CPoint curPt, Coord3D *newPt, Bool constrain=true) override; virtual Bool docToViewCoords(Coord3D curPt, CPoint* newPt) override; - virtual void updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange) override; + virtual void updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange, Bool invalObjects = true) override; /// Invalidates an object. Pass null to inval all objects. virtual void invalObjectInView(MapObject *pObj) override; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/TileTool.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/TileTool.cpp index aa2688ecb2a..05441be5066 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/TileTool.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/TileTool.cpp @@ -170,7 +170,9 @@ void TileTool::mouseMoved(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldB if (fullUpdate) { m_htMapEditCopy->optimizeTiles(); // force to optimize tileset } - pDoc->updateHeightMap(m_htMapEditCopy, !fullUpdate, partialRange); + // Painting tiles or pathing never changes heights, so skip refitting every object, + // road, light and scorch to the terrain on each mouse move. + pDoc->updateHeightMap(m_htMapEditCopy, !fullUpdate, partialRange, false); } pView->UpdateWindow(); m_prevViewPt = viewPt; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp index a7cfdabe42d..ba5d61deb4a 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -1392,7 +1392,7 @@ void CWorldBuilderDoc::updateAllViews() } } -void CWorldBuilderDoc::updateHeightMap(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange) +void CWorldBuilderDoc::updateHeightMap(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange, Bool invalObjects) { POSITION pos = GetFirstViewPosition(); while (pos != nullptr) @@ -1400,7 +1400,7 @@ void CWorldBuilderDoc::updateHeightMap(WorldHeightMap *htMap, Bool partial, cons CView* pView = GetNextView(pos); WbView* pWView = (WbView *)pView; ASSERT_VALID(pWView); - pWView->updateHeightMapInView(htMap, partial, partialRange); + pWView->updateHeightMapInView(htMap, partial, partialRange, invalObjects); pWView->Invalidate(); } } diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp index e77cce6a642..eb8ece86bcb 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp @@ -1575,7 +1575,7 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn) // ---------------------------------------------------------------------------- -void WbView3d::updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange) +void WbView3d::updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange, Bool invalObjects) { if (htMap == nullptr) return; @@ -1612,7 +1612,10 @@ void WbView3d::updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const if (curTicks < 1) curTicks = 1; } - invalObjectInView(nullptr); // update all the map objects, to account for ground changes + // A full rebuild always refits objects; a partial update only when heights may have changed. + if (invalObjects || !partial) { + invalObjectInView(nullptr); // update all the map objects, to account for ground changes + } --m_updateCount; }