Skip to content

fix(heightmap): Fix up view and heightmap to work better with low camera pitch#2677

Open
xezon wants to merge 6 commits intoTheSuperHackers:mainfrom
xezon:xezon/implement-low-pitch-oversize-terrain
Open

fix(heightmap): Fix up view and heightmap to work better with low camera pitch#2677
xezon wants to merge 6 commits intoTheSuperHackers:mainfrom
xezon:xezon/implement-low-pitch-oversize-terrain

Conversation

@xezon
Copy link
Copy Markdown

@xezon xezon commented May 2, 2026

Merge with Rebase

This change is quite a bit heavy but is split into 6 commits for ease of review. It fixes and improves several aspects of camera and heightmap:

  1. Aligns the far clip plane with the actual terrain size, unless m_FXPitch is set (used by scripted camera) or the entire terrain is drawn. This is great to only draw as far as really needed: good for performance.

  2. Removes useless logic in function HeightMapRenderObjClass::updateCenter because if (TheTacticalView->getFieldOfView() != 0) always returns true.

  3. The full terrain update is now done after the new terrain origin position has been set, so that it will draw at the correct location straight away. This fixes issues where the terrain was not properly drawn when jumped to from far away.

  4. The terrain now only really updates if the origin position has been changed. Originally this was not guaranteed which could have lead to bad performance issues if an origin point was located far outside the map boundaries.

  5. Implements a new functionHeightMapRenderObjClass::setTerrainDrawSize to set custom draw sizes needed for the final commit. This function has a bit of a strange contract in relation to HeightMapRenderObjClass::oversizeTerrain, but that is needed to preserve original behavior in scripted mission cinematics.

  6. At last, the camera and heightmap now renders a larger terrain area when the camera is pitched below 37 degrees. Tip: Disable whitespace to see a cleaner change diff.

Known issues

The game client might stall when pitching down and passing the threshold of 37 degrees because the heightmap update is expensive and needs improving.

TODO

  • Add pull id to commit titles

@xezon xezon added this to the Camera Improvements milestone May 2, 2026
@xezon xezon added Enhancement Is new feature or request Major Severity: Minor < Major < Critical < Blocker Performance Is a performance concern Gen Relates to Generals ZH Relates to Zero Hour Fix Is fixing something, but is not user facing labels May 2, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 2, 2026

Greptile Summary

This PR improves camera and heightmap rendering at low pitch angles by switching to a doubled draw area below 37°, aligns the far clip plane with the actual terrain draw extent for better performance, and fixes the ordering of terrain updates (origin set before full rebuild). It also refactors setDrawOrg into separate createDrawArea/setDrawArea functions and adds a new setTerrainDrawSize virtual that lets the view control draw dimensions independently of mission-script oversizing.

  • Low-pitch terrain: updateTerrain selects LOW_ANGLE_DRAW_WIDTH/HEIGHT (2× the tile count) when the camera pitch drops below 37°, and a fast camera-pivot-based approximation replaces the frustum-intersection path in updateCenter for that range.
  • Dynamic far clip plane: updateCameraClipPlanes now projects the terrain bounding box along the camera direction to compute the minimum necessary far Z, replacing the fixed scaled constant — skipped when m_drawEntireTerrain or m_FXPitch is set.
  • Correctness fixes: m_needFullUpdate now sets the draw area before calling updateBlock, terrain origin is established before the full rebuild, and the WorldBuilder callers now pre-clamp m_partialMapSize to the map extent before passing it to the assertion-guarded setDrawWidth/Height.

Confidence Score: 5/5

The change is safe to merge; the refactored terrain update ordering and new low-pitch draw path are well-contained and the known stall on threshold crossing is documented.

All changed code paths guard correctly against null terrain/map pointers, the m_needFullUpdate fix properly sets the draw area before rebuilding, and the WorldBuilder callers now clamp draw sizes before the assertion-guarded setters. The only finding is a stale year in one comment.

No files require special attention beyond the minor comment date in W3DView.cpp.

Important Files Changed

Filename Overview
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Adds low-pitch terrain draw logic in updateTerrain, moves updateCameraClipPlanes to run after terrain update, and rewrites clip plane calculation to use actual terrain bounding box. Minor stale date in comment.
Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp New setTerrainDrawSize function centralises draw-size resizing; oversizeTerrain now stores oversize dimensions in m_oversizeDrawWidth/Height; updateCenter splits into a high-pitch frustum path and a fast low-pitch approximation using the camera pivot. m_needFullUpdate now correctly sets the draw area before the full rebuild.
Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp Splits setDrawOrg into createDrawArea (pure clamping) + setDrawArea (mutation), making origin/size changes atomic and testable. Clamping logic is preserved and the setDrawOrg wrapper maintains backward compatibility.
Core/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp Adapts updateCenter to new signature and adds no-op setTerrainDrawSize override for the flat map variant.
Core/GameEngineDevice/Include/W3DDevice/GameClient/WorldHeightMap.h Adds DrawArea struct, LOW_ANGLE_DRAW_WIDTH/HEIGHT constants, replaces silent-clamp setDrawWidth/Height with assertion-guarded variants, and declares createDrawArea/setDrawArea.
Core/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h Updates virtual interface: updateCenter gains cameraPivot, oversizeTerrain and new setTerrainDrawSize become pure virtual.
Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp Passes m_cameraTarget as the new cameraPivot argument and explicitly clamps m_partialMapSize to the map extent before calling setDrawWidth/Height.
GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp Mirror of the Generals WorldBuilder fix: same cameraPivot threading and setDrawWidth/Height clamping.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp:3710-3714
The comment date `31/12/2025` references a year prior to the current year (2026). Per the team's convention, newly added code comments should reference the current year.

```suggestion
	else
	{
		// TheSuperHackers @tweak xezon 01/01/2026 Increases visible terrain area when lowering the camera pitch.
		// Note: The default camera pitch in Generals was 37.5, which we prefer to keep the normal draw size for.
		drawWidth = WorldHeightMap::LOW_ANGLE_DRAW_WIDTH;
```

Reviews (5): Last reviewed commit: "fix(heightmap): Properly draw larger ter..." | Re-trigger Greptile

Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp
@xezon xezon force-pushed the xezon/implement-low-pitch-oversize-terrain branch from 02bc55f to 638dacf Compare May 3, 2026 09:28
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Outdated
@DevGeniusCode
Copy link
Copy Markdown

How to check the PR? Do I need GenTool to play with the camera height?

@xezon
Copy link
Copy Markdown
Author

xezon commented May 3, 2026

How to check the PR? Do I need GenTool to play with the camera height?

In Debug build, camera can be pitched with Comma key.

@xezon xezon force-pushed the xezon/implement-low-pitch-oversize-terrain branch 2 times, most recently from 3a3b654 to 1c499cd Compare May 3, 2026 10:08
@xezon
Copy link
Copy Markdown
Author

xezon commented May 3, 2026

There is a performance degradation in Generals Shell Map which needs looking into.

Skyaero42
Skyaero42 previously approved these changes May 3, 2026
Copy link
Copy Markdown

@Skyaero42 Skyaero42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disregard

@Skyaero42 Skyaero42 dismissed their stale review May 3, 2026 12:11

too early, only checked the first commit - forgot that there were six

Comment thread Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h Outdated
@xezon
Copy link
Copy Markdown
Author

xezon commented May 3, 2026

There is a bug in Generals where jumping far positions will render the terrain black for 1 frame. Needs looking into.

}

constexpr const Int cellOffset = 1;
const Real cameraPitch = WWMath::Asin(fabsf(camera->Get_Forward_Dir().Z));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps use asin(..) as WWMath is looking to become the place for deterministic math. Two times in this PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp
@xezon xezon force-pushed the xezon/implement-low-pitch-oversize-terrain branch from 1c499cd to 7321494 Compare May 5, 2026 17:19
@xezon
Copy link
Copy Markdown
Author

xezon commented May 5, 2026

There is a performance degradation in Generals Shell Map which needs looking into.

Fixed.

Comment thread Core/GameEngineDevice/Include/W3DDevice/GameClient/WorldHeightMap.h Outdated
Copy link
Copy Markdown

@Skyaero42 Skyaero42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@xezon
Copy link
Copy Markdown
Author

xezon commented May 5, 2026

There is a bug in Generals where jumping far positions will render the terrain black for 1 frame. Needs looking into.

This problem is already in main branch before this change and is now tracked as an issue.

@xezon xezon force-pushed the xezon/implement-low-pitch-oversize-terrain branch from 7321494 to dbc5175 Compare May 5, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Is new feature or request Fix Is fixing something, but is not user facing Gen Relates to Generals Major Severity: Minor < Major < Critical < Blocker Performance Is a performance concern ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants