feat(view): Save position and view direction of player camera in MSG_SET_REPLAY_CAMERA#2631
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp | Refactored setCameraTransform into updateCameraTransform/updateCameraClipPlanes/setCameraTransform(Matrix3D); added get3DCameraDirection and set3DCameraLookAt. Minor: direction not normalized before Look_At_Dir. |
| Core/GameEngine/Include/GameClient/View.h | Changed get3DCameraPosition from pure virtual returning const ref to virtual returning by value; added get3DCameraDirection and set3DCameraLookAt virtuals with no-op defaults, removing dead overrides in LineDraw. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp | Backward-compatible replay camera dispatch: args 4/5 hoisted, args 6/7 (camPos, camDir) read only when getArgumentCount() >= 8, then applied via set3DCameraLookAt. |
| Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp | Same backward-compatible replay camera dispatch changes as GeneralsMD counterpart. |
| GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | Appends two new location arguments (camPos, camDir via get3DCameraPosition/get3DCameraDirection) to MSG_SET_REPLAY_CAMERA messages for new replays. |
| Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | Same replay camera message encoding changes as GeneralsMD counterpart. |
| Core/Libraries/Include/Lib/BaseType.h | Added Coord3D::is(Real) utility method for component-wise equality check against a scalar, mirroring the existing pattern on Coord2D and ICoord2D. |
| Core/Libraries/Source/WWVegas/WWMath/matrix3d.cpp | Added Look_At_Dir method (extracted from Look_At) used by set3DCameraLookAt; constructs a camera transform from position and direction vector. |
| GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/camera.cpp | Added Get_Right_Dir, Get_Forward_Dir, Get_Up_Dir helpers derived from the camera's orthonormal transform columns. |
| Generals/Code/Libraries/Source/WWVegas/WW3D2/camera.cpp | Same Get_Right_Dir/Get_Forward_Dir/Get_Up_Dir helpers as GeneralsMD counterpart. |
Sequence Diagram
sequenceDiagram
participant LA as LookAtXlat
participant MS as MessageStream
participant GL as GameLogicDispatch
participant TV as TheTacticalView (W3DView)
participant CAM as CameraClass
Note over LA: Each game tick (recording)
LA->>TV: get3DCameraPosition()
TV->>CAM: Get_Position()
CAM-->>TV: Vector3
TV-->>LA: Coord3D camPos
LA->>TV: get3DCameraDirection()
TV->>CAM: Get_Forward_Dir() = -Get_Z_Vector()
CAM-->>TV: Vector3
TV-->>LA: Coord3D camDir
LA->>MS: appendMessage(MSG_SET_REPLAY_CAMERA)
LA->>MS: appendLocationArgument(pos, angle, pitch, zoom, cursor, mousePos)
LA->>MS: appendLocationArgument(camPos) [arg 6]
LA->>MS: appendLocationArgument(camDir) [arg 7]
Note over GL: Each game tick (playback)
GL->>GL: getArgumentCount() >= 8?
alt New replay >= 8 args
GL->>TV: userSetPosition / Angle / Pitch / Zoom
GL->>TV: setUserControlled(false)
GL->>TV: set3DCameraLookAt(camPos, camDir, 0)
TV->>TV: Look_At_Dir(camPos, camDir, roll)
TV->>TV: updateCameraClipPlanes()
TV->>CAM: Set_Transform(matrix)
TV->>TV: m_recalcCamera = false
else Old replay < 8 args
GL->>TV: userSetPosition / Angle / Pitch / Zoom only
end
GL->>TV: lockUserControlUntilFrame(frame+1)
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Line: 824-835
Comment:
**Normalize direction vector before `Look_At_Dir`**
`Look_At_Dir` is implemented using `sinp = dir.Z` and `cosp = sqrt(dir.X² + dir.Y²)`, which are only valid sin/cos values when the input direction is a unit vector. While the direction is read from an orthonormal camera transform and should be unit-length, a small normalization guard would make this robust against any accumulated floating-point drift in a long replay.
```suggestion
Vector3 camPos(pos.x, pos.y, pos.z);
Vector3 camDir(dir.x, dir.y, dir.z);
camDir.Normalize();
Matrix3D transform;
transform.Look_At_Dir(camPos, camDir, roll);
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (4): Last reviewed commit: "Replicate in Generals" | Re-trigger Greptile
|
Generals fails to compile until replicated. |
aaf13c1 to
c6cd02e
Compare
|
Replicated in Generals with conflict in wbview.cpp |
This change saves the position and view direction of the player camera in MSG_SET_REPLAY_CAMERA.
This way, in new replays (single player), the camera will always be at the exact location that the player recorded the replay with. This has advantages and disadvantages:
Advantages
Disadvantages
Further considerations
This may need another look in the future, especially if we plan to store player camera in Multiplayer replays.
TODO