fix(view): Introduce PRESERVE_RETAIL_SCRIPTED_CAMERA and fix or improve camera offset and zoom calculations#2524
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp | Major refactor: removes m_cameraOffset member, introduces getCameraOffsetZ/getDesiredHeight/getMaxHeight/getDesiredZoom/getMaxZoom helpers, recalculates camera offset inline in buildCameraPosition, and adds PRESERVE_RETAIL_SCRIPTED_CAMERA guards throughout. Minor issues: two new comments reference 2025 dates, and a constexpr const redundancy. |
| Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h | Removes m_cameraOffset field, adds m_initialGroundLevel under PRESERVE_RETAIL_SCRIPTED_CAMERA guard, and declares the five new private helper methods. Clean change. |
| Core/GameEngine/Include/Common/GameDefines.h | Adds the PRESERVE_RETAIL_SCRIPTED_CAMERA preprocessor macro with a default value of 1, following the same pattern as PRESERVE_RETAIL_BEHAVIOR. No issues. |
| GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h | Guards m_cameraHeight field behind PRESERVE_RETAIL_SCRIPTED_CAMERA, correctly pairing with the new macro. No issues. |
| GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp | Guards the CameraHeight INI parser entry and its default initializer behind PRESERVE_RETAIL_SCRIPTED_CAMERA. Column alignment in the INI parse table is preserved. No issues. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
BCP["buildCameraPosition()"]
GCZ["getCameraOffsetZ()"]
PRSC{PRESERVE_RETAIL_SCRIPTED_CAMERA
&& !m_isUserControlled}
SCRIPTED["m_initialGroundLevel + m_cameraHeight"]
USER["m_groundLevel + m_maxCameraHeight"]
SRCPOS["sourcePos.Z = cameraOffsetZ\nsourcePos.Y = -(Z / tan(pitch))\nsourcePos.X = -(Y * tan(yaw))"]
GDZ["getDesiredZoom(x,y)"]
ZLIMIT{"isZoomLimited()
&& !isUserControlLocked()"}
KEEPZ["return m_zoom (unchanged)"]
GDH["getDesiredHeight(x,y)"]
DIVZ["desiredHeight / getCameraOffsetZ()"]
GMZ["getMaxZoom(x,y)"]
GMH["getMaxHeight(x,y)"]
DIVM["maxHeight / getCameraOffsetZ()"]
SUC["setUserControlled(value)"]
REMAP["m_zoom = getDesiredZoom(pos.x, pos.y)\n(remap zoom across scripted/user boundary)"]
BCP --> GCZ
GCZ --> PRSC
PRSC -->|yes| SCRIPTED
PRSC -->|no| USER
SCRIPTED --> SRCPOS
USER --> SRCPOS
GDZ --> ZLIMIT
ZLIMIT -->|early return| KEEPZ
ZLIMIT -->|compute| GDH
GDH --> DIVZ
DIVZ --> GCZ
GMZ --> GMH
GMH --> DIVM
DIVM --> GCZ
SUC -->|PRESERVE_RETAIL_SCRIPTED_CAMERA| REMAP
REMAP --> GDZ
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Line: 649-666
Comment:
**Date references prior to current year (2026)**
Two newly introduced comment annotations reference dates in 2025, which is prior to the current year (2026). Per the project's policy, newly created code comments should reference the current year.
Line 649:
```suggestion
// TheSuperHackers @info xezon 04/12/2026 It is necessary to use the initial ground level for the
```
Line 666:
```suggestion
// TheSuperHackers @info xezon 06/12/2026 The height above ground must be relative to the current
```
**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: 2509
Comment:
**`constexpr const` is redundant**
`constexpr` already implies `const` in C++, so `const` here is redundant.
```suggestion
constexpr Real MAX_GROUND_LEVEL = 120.0f;
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(view): Move camera offset calculatio..." | Re-trigger Greptile
This change is quite a bit complicated.
PRESERVE_RETAIL_SCRIPTED_CAMERA
Introduces a new PRESERVE_RETAIL_SCRIPTED_CAMERA preprocessor macro to preserve the original look of the scripted camera. Most importantly the initial ground level is cached and used during scripted camera movements.
Camera Offset
The camera offset is now freshly calculated inside
W3DView::buildCameraPosition, instead of various other locations, to make sure that it is always correctly built when the camera pitch or angle changes.Camera Zoom
The camera zoom was changed from originally
initialGroundLevel + TheGlobalData->m_cameraHeightto
currentGroundLevel + TheGlobalData->m_maxCameraHeightThis effectively means that the camera zoom range is now 0 to 1. Originally it was 0 to N, where N would generally be 1.33 or higher. This was confusing. The new setup gives a much better expectation for what a zoom value represents. 0.5 now means half way zoomed from max possible height to ground.
Known issues
TODO