bugfix(view): Fix view ray cast behavior for mouse picks and drawable occlusion#2818
bugfix(view): Fix view ray cast behavior for mouse picks and drawable occlusion#2818xezon wants to merge 7 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Core/Libraries/Source/WWVegas/WWMath/plane.h | Compute_Intersection return type changed from bool to IntersectionResType enum; all callers that previously tested the bool either don't check the return value (polygon clippers) or were explicitly updated to == INSIDE_SEGMENT. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp | screenToTerrain and screenToWorldAtZ correctly return failure codes without writing to output parameters; pick-ray extended to sqr(depth); getAxisAlignedViewRegion falls back to heightmap region on partial frustum intersection. |
| Core/GameEngine/Source/GameClient/View.cpp | getScreenCornerWorldPointsAtZ returns combined IntersectionResType; viewport-relative corner calculation added; correctly propagates NO_INTERSECTION and OUTSIDE_LINE from per-corner results. |
| Core/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp | m_reconstructViewBox flag cleared at function start so early-returns on NO_INTERSECTION don't cause an every-frame retry; variable renames improve clarity. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp | New getDrawRegion2D() helper extracts the repeated draw-region-to-world-space calculation into one place; correctly accounts for border size. |
| GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | Not modified in this PR; contains several unchecked screenToTerrain calls that now have subtly changed failure behavior — previously world would be written with (0,0,0); now it is left uninitialized when false is returned. |
| Core/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp | anchorEnd terrain conversion now guarded and only performed when isLineBuild; worldStart/worldEnd variables correctly scoped; placeBuildAvailable(nullptr) cancellation on sky pick is correct. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User as Mouse Input
participant Xlat as MessageTranslator
participant View as W3DView
participant Plane as PlaneClass
participant Terrain as TerrainRenderObj
User->>Xlat: MSG_MOUSE_LEFT_CLICK (screen coord)
Xlat->>View: "screenToTerrain(screen, &world)"
View->>View: "getPickRay() → rayStart, rayEnd (len=sqr(depth))"
View->>Terrain: Cast_Ray(raytest)
alt terrain hit
Terrain-->>View: ContactPoint
View-->>Xlat: true (world set)
Xlat->>Xlat: appendMessage(MSG_DO_MOVE / etc.)
else no terrain hit (sky)
Terrain-->>View: no hit
View-->>Xlat: false (world unchanged)
Xlat->>Xlat: break — command discarded
end
Note over View,Plane: screenToWorldAtZ path
View->>Plane: "Compute_Intersection(rayStart, rayEnd, &t)"
alt t in [0,1]
Plane-->>View: INSIDE_SEGMENT
else t outside [0,1]
Plane-->>View: OUTSIDE_LINE
else ray parallel
Plane-->>View: NO_INTERSECTION
end
View-->>View: "set world coords only if != NO_INTERSECTION"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User as Mouse Input
participant Xlat as MessageTranslator
participant View as W3DView
participant Plane as PlaneClass
participant Terrain as TerrainRenderObj
User->>Xlat: MSG_MOUSE_LEFT_CLICK (screen coord)
Xlat->>View: "screenToTerrain(screen, &world)"
View->>View: "getPickRay() → rayStart, rayEnd (len=sqr(depth))"
View->>Terrain: Cast_Ray(raytest)
alt terrain hit
Terrain-->>View: ContactPoint
View-->>Xlat: true (world set)
Xlat->>Xlat: appendMessage(MSG_DO_MOVE / etc.)
else no terrain hit (sky)
Terrain-->>View: no hit
View-->>Xlat: false (world unchanged)
Xlat->>Xlat: break — command discarded
end
Note over View,Plane: screenToWorldAtZ path
View->>Plane: "Compute_Intersection(rayStart, rayEnd, &t)"
alt t in [0,1]
Plane-->>View: INSIDE_SEGMENT
else t outside [0,1]
Plane-->>View: OUTSIDE_LINE
else ray parallel
Plane-->>View: NO_INTERSECTION
end
View-->>View: "set world coords only if != NO_INTERSECTION"
Reviews (3): Last reviewed commit: "Move rayStart.Set back" | Re-trigger Greptile
… occlusion and radar box
7c85fda to
0db89be
Compare
This change fixes view ray casting behavior for mouse picks and drawable occlusion. The behavior for the radar view box is still not working correctly at low camera pitch but is otherwise still ok for regular top-down camera views. I do not yet know how to deal with the view box at low camera pitch.
The view ray now has a very long range making sure that the camera far clip plane is not limiting mouse picks. Also, view rays into the sky will no longer send units to 0,0,0: Invalid ray picks are now treated as no input.
The drawable updates made in the area created with
getAxisAlignedViewRegionare now working with low camera pitch. The function falls back to the terrain draw area if the view frustum does not fully intersect with the Z plane.Known issues
The Radar View Box still looks bad at low camera pitch as did always.
TODO