Skip to content

bugfix(view): Fix ground level of bookmarks, replay camera and game world microphone#2595

Open
xezon wants to merge 6 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-view-groundlevel
Open

bugfix(view): Fix ground level of bookmarks, replay camera and game world microphone#2595
xezon wants to merge 6 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-view-groundlevel

Conversation

@xezon
Copy link
Copy Markdown

@xezon xezon commented Apr 12, 2026

This change fixes the ground level of bookmarks, replay camera and the game world microphone by merging View::m_groundLevel into View::m_pos::z.

View::m_pos::z was originally unused and View::m_groundLevel was effectively that. They are now consolidated which automatically adds the ground level into bookmarks and the replay camera through ViewLocation (cool).

The game world microphone, used for positional audio, did not calculate the microphone height correctly which was fixed as well.

In View::lookAt the pivot is now reset to the ground which corrects behavior as well.

TODO

  • Replicate in Generals
  • Test a few cutscenes

@xezon xezon added this to the Camera Improvements milestone Apr 12, 2026
@xezon xezon added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Refactor Edits the code with insignificant behavior changes, is never user facing ThisProject The issue was introduced by this project, or this task is specific to this project labels Apr 12, 2026
@xezon
Copy link
Copy Markdown
Author

xezon commented Apr 12, 2026

Generals will fail to compile until replicated.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 12, 2026

Greptile Summary

This PR consolidates W3DView::m_groundLevel into View::m_pos.z, fixing ground level tracking in bookmarks, replay camera, and the game world audio microphone. The change is a clean architectural improvement: m_pos.z is now the canonical ground level, forwarded through ViewLocation so bookmarks and replay camera automatically persist it, and the microphone height calculation is corrected to properly account for terrain elevation offset.

Confidence Score: 5/5

Safe to merge — clean architectural consolidation with no critical bugs found.

All call sites are consistently updated. The prior P1 concern (camera slave mode corrupting m_pos.z) was already resolved. forceRedraw() removal from setLocation is safe because setPitch — called within that same function — already sets both m_recalcCamera and m_cameraAreaConstraintsValid. Audio microphone math is semantically equivalent and more correct. Waypoint ground-height storage via waypoints[].z is properly computed across all code paths.

No files require special attention.

Important Files Changed

Filename Overview
Core/GameEngine/Include/GameClient/View.h API modernized: pointer-based getPosition/setPosition replaced with reference/value returns; new setPosition2D/getPosition2D helpers added; m_pos.z todo-comment removed now that z is used.
Core/GameEngine/Source/GameClient/View.cpp Position access updated to new API; forceRedraw() safely removed from setLocation since setPitch (called inside) already sets m_recalcCamera and m_cameraAreaConstraintsValid.
Core/GameEngine/Source/Common/Audio/GameAudio.cpp Microphone placement corrected: desiredHeightAbs now accounts for terrain elevation, zScale uses relative height, and cameraPivot.z (smoothed ground level) replaces the explicit getGroundHeight call.
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Comprehensive replacement of m_groundLevel with m_pos.z throughout; waypoint path now stores ground height in waypoints[].z instead of the removed groundHeight[]; lookAt correctly calls resetPivotToGround after setting position.
Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h m_groundLevel field removed; groundHeight[] array removed from TMoveAlongWaypointPathInfo; m_initialGroundLevel retained for PRESERVE_RETAIL_SCRIPTED_CAMERA path.
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp Debug display updated to use getPosition() directly; getGroundHeight call removed since m_pos.z already carries the smoothed terrain height.
Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp Updated userSetPosition call site to pass by reference, matching the new API signature.
GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp Same userSetPosition call-site update as Generals mirror, consistent with the new API.

Sequence Diagram

sequenceDiagram
    participant Game as Game Loop
    participant W3DView
    participant View as View (base)
    participant Audio as AudioManager
    participant Terrain as TerrainLogic

    Note over W3DView,View: m_pos.z now carries ground level (was m_groundLevel)

    Game->>W3DView: movePivotToGround()
    W3DView->>Terrain: getGroundHeight(x, y)
    Terrain-->>W3DView: terrainZ
    W3DView->>View: m_pos.z += delta (smooth adjust toward terrain)

    Game->>W3DView: buildCameraPosition()
    W3DView->>View: getPosition() → m_pos (x,y,z=groundLevel)
    W3DView->>W3DView: heightScale = 1 - (m_pos.z / sourcePos.Z)
    W3DView->>W3DView: targetPos.Z = m_pos.z

    Game->>Audio: update()
    Audio->>W3DView: getPosition() → cameraPivot (z=groundLevel)
    Audio->>W3DView: get3DCameraPosition() → cameraPos
    Audio->>Audio: groundToCameraVector = cameraPos - cameraPivot
    Audio->>Audio: desiredHeightAbs = desiredHeightRel + cameraPivot.z
    Audio->>Audio: microphonePos = cameraPivot + scale * groundToCameraVector

    Game->>W3DView: getLocation(bookmark)
    W3DView->>View: getLocation() → ViewLocation (pos incl z=groundLevel)
    Note over View: ViewLocation now stores z (ground level)

    Game->>W3DView: setLocation(bookmark)
    W3DView->>View: setLocation() → setPosition(pos incl z)
    Note over View: Ground level restored from bookmark
Loading

Reviews (6): Last reviewed commit: "Replicate in Generals" | Re-trigger Greptile

Comment thread Core/GameEngine/Source/Common/Audio/GameAudio.cpp Outdated
Comment thread Core/GameEngine/Include/GameClient/View.h
Comment thread Core/GameEngine/Include/GameClient/View.h
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Outdated
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
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 to me. May also want to await @Mauller approval before merging

Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Outdated
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
@xezon xezon force-pushed the xezon/fix-view-groundlevel branch from 3aa88fb to e5ff233 Compare April 14, 2026 19:42
Comment thread Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Outdated
Copy link
Copy Markdown

@Mauller Mauller 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, although what greptile brought up might want checking. But i don't see how it changes behaviour.

@xezon
Copy link
Copy Markdown
Author

xezon commented Apr 15, 2026

There are cutscene discrepancies in Generals that need looking into.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker Refactor Edits the code with insignificant behavior changes, is never user facing ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants