bugfix(view): Fix and improve camera area constraints and camera pivoting#2506
Conversation
|
I recreated #2480 because I merged it incorrectly to main branch prior. |
9c4e01a to
41209ea
Compare
|
| Filename | Overview |
|---|---|
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp | Core camera logic overhaul: introduces zoomCameraToDesiredHeight/movePivotToGround split, deferred constraint recalc after scrolling, and moves clipping out of setCameraTransform into updateCameraAreaConstraints; one date-convention violation and a duplicate separator found. |
| Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h | Adds resetPivotToGround override, m_recalcCameraConstraintsAfterScrolling member, and new private helper declarations; forceCameraAreaConstraintRecalc now lazily invalidates instead of eagerly recalculating. |
| Core/GameEngine/Include/GameClient/View.h | Adds resetPivotToGround virtual method to the base View interface and exposes userResetPivotToGround as a user-action helper. |
| Core/Libraries/Include/Lib/BaseType.h | Adds zero() helpers to RealRange/Coord2D/ICoord2D/Region2D/IRegion2D/IRegion3D, isInRegion(x,y) to Region2D/IRegion2D, and renames Region3D::isInRegionWithZ to isInRegion; no existing callers of the old name found. |
| Core/Libraries/Source/WWVegas/WWMath/wwmath.h | Adds Inverse_Lerp(float/double) utility functions and renames Lerp parameter from 'lerp' to 't'; no division-by-zero guard in Inverse_Lerp. |
| Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp | resetCamera now uses userResetPivotToGround + individual user actions instead of a positional resetCamera call, aligning Generals and GeneralsMD implementations. |
| GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | Same resetCamera refactor as Generals counterpart. |
| Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | Middle-click camera reset now calls userResetPivotToGround before resetting angle/pitch/zoom. |
| GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | Same middle-click pivot reset as Generals counterpart. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[W3DView::update] --> B{m_okToAdjustHeight?}
B -- No --> H
B -- Yes --> C{adjustZoomWhenScrolling or adjustZoomWhenNotScrolling?}
C -- No --> E
C -- Yes --> D1[zoomCameraToDesiredHeight]
D1 --> D2[movePivotToGround]
D2 --> D3{isZoomingOrMovingPivot?}
D3 -- No --> E
D3 -- Yes --> D4{isScrolling?}
D4 -- Yes --> D5[m_recalcCameraConstraintsAfterScrolling = true]
D4 -- No --> D6[m_cameraAreaConstraintsValid = false]
D5 --> E
D6 --> E
E{m_recalcCameraConstraintsAfterScrolling && !isScrolling?}
E -- Yes --> F[m_cameraAreaConstraintsValid = false]
E -- No --> G
F --> G
G{isTimeFast?}
G -- Yes --> RET[return early]
G -- No --> H[updateCameraAreaConstraints]
H --> H1{m_cameraAreaConstraintsValid?}
H1 -- No --> H2[calcCameraAreaConstraints]
H2 --> H3
H1 -- Yes --> H3{isWithinCameraAreaConstraints?}
H3 -- No --> H4[clipCameraIntoAreaConstraints + m_recalcCamera=true]
H3 -- Yes --> I
H4 --> I{m_recalcCamera?}
I -- Yes --> J[setCameraTransform]
I -- No --> K[End]
J --> K
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Line: 1419
Comment:
**Comment date references prior year**
This newly added comment references `26/10/2025`, which is prior to the current year (2026). Per the project's convention, dates in newly created comments should reflect the current year.
```suggestion
// TheSuperHackers @bugfix xezon 26/10/2026 The camera area constraints are now recalculated when
```
**Rule Used:** What: Flag newly created code comments that refere... ([source](https://app.greptile.com/review/custom-context?memory=fd72a556-4fd8-4db4-8b08-8e51516a64ad))
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Line: 2455-2456
Comment:
**Duplicate separator line**
Two consecutive `//---` separator lines appear before `resetPivotToGround`. The rest of the codebase consistently uses only a single separator line between functions. The extra line is likely unintentional.
```suggestion
//-------------------------------------------------------------------------------------------------
void W3DView::resetPivotToGround( void )
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: Core/Libraries/Source/WWVegas/WWMath/wwmath.h
Line: 278-285
Comment:
**`Inverse_Lerp` has no division-by-zero guard**
When `a == b`, `(b - a)` is `0.0f` and both overloads will produce `NaN` or `±Inf`. The current call site in `movePivotToGround` uses compile-time distinct constants (`DEG_TO_RADF(15.f)` and `DEG_TO_RADF(30.f)`), so there is no current bug. However, as a general-purpose utility exposed in a header, it is worth adding an early-return guard to prevent silent issues in future callers.
```cpp
WWINLINE float WWMath::Inverse_Lerp(float a, float b, float v)
{
const float denom = b - a;
return (denom != 0.0f) ? (v - a) / denom : 0.0f;
}
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "bugfix(view): Fix and improve camera piv..." | Re-trigger Greptile
Merge with Rebase
The camera area constraints are now recalculated when the camera zoom changes, for example because of terrain elevation changes in the camera's view. The camera will be smoothly pushed away from the constraints, but not while the user is scrolling, to make the scrolling along the map border a pleasant experience. This behavior ensures that the view can reach and see all areas of the map, and especially the bottom map border. The camera can now also be moved a bit closer to the map edges. All this is very useful to avoid issues where some units or structures are not possible to get into the view, for example a Chinook at a Supply at the top edge of a map (TheSuperHackers/GeneralsRankedMaps#7). Or a Dozer at the bottom edge of a valley on Defcon 6.
Additionally the camera pivoting was fixed. The camera now repositions correctly towards its ground pivot instead of zooming to a pivot that is not aligned to the terrain ground. User facing this looks identical, but technically it is different. Scrolling to different locations of the map will now keep the camera pivot always correctly centered to the ground. It is no longer necessary to press Numpad 5 to recenter the pivot.
This change also implicitly fixes the broken scripted camera in the USA 01 intro, which was introduced by change #2291.
Known issues
The scripted camera will not always position perfectly at the original locations when the ground pivot was changed. This will be fixed in a future change.