Skip to content

Commit 91ba717

Browse files
committed
Merge remote-tracking branch 'origin/hotfix-1.16' into hotfix-1.16-ue5
2 parents 60ae940 + 6e87128 commit 91ba717

File tree

6 files changed

+94
-41
lines changed

6 files changed

+94
-41
lines changed

CHANGES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Change Log
22

3+
### v1.16.2 - 2022-08-04
4+
5+
##### Fixes :wrench:
6+
7+
- Fixed a bug that caused a crash in Unreal Engine 4.26 when enabling the experimental tileset occlusion culling feature.
8+
9+
In addition to the above, this release updates [cesium-native](https://github.com/CesiumGS/cesium-native) from v0.18.0 to v0.18.1. See the [changelog](https://github.com/CesiumGS/cesium-native/blob/main/CHANGES.md) for a complete list of changes in cesium-native.
10+
311
### v1.16.1 - 2022-08-01
412

513
##### Fixes :wrench:

CesiumForUnreal.uplugin

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"FileVersion": 3,
3-
"Version": 31,
4-
"VersionName": "1.16.1",
3+
"Version": 32,
4+
"VersionName": "1.16.2",
55
"FriendlyName": "Cesium for Unreal",
66
"Description": "Unlock the 3D geospatial ecosystem in Unreal Engine with real-world 3D content and a high accuracy full-scale WGS84 globe.",
77
"Category": "Geospatial",

Source/CesiumRuntime/Private/CesiumViewExtension.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@ TileOcclusionState CesiumViewExtension::getPrimitiveOcclusionState(
2323

2424
for (const SceneViewOcclusionResults& viewOcclusionResults :
2525
_currentOcclusionResults.occlusionResultsByView) {
26-
const FPrimitiveOcclusionHistory* pHistory =
27-
viewOcclusionResults.PrimitiveOcclusionHistorySet.Find(
28-
FPrimitiveOcclusionHistoryKey(id, 0));
26+
const PrimitiveOcclusionResult* pOcclusionResult =
27+
viewOcclusionResults.PrimitiveOcclusionResults.Find(id);
2928

30-
if (pHistory && pHistory->LastConsideredTime >= frameTimeCutoff) {
31-
if (!pHistory->OcclusionStateWasDefiniteLastFrame) {
29+
if (pOcclusionResult &&
30+
pOcclusionResult->LastConsideredTime >= frameTimeCutoff) {
31+
if (!pOcclusionResult->OcclusionStateWasDefiniteLastFrame) {
3232
return TileOcclusionState::OcclusionUnavailable;
3333
}
3434

3535
if (previouslyOccluded) {
36-
if (pHistory->LastPixelsPercentage > 0.01f) {
36+
if (pOcclusionResult->LastPixelsPercentage > 0.01f) {
3737
return TileOcclusionState::NotOccluded;
3838
}
39-
} else if (!pHistory->WasOccludedLastFrame) {
39+
} else if (!pOcclusionResult->WasOccludedLastFrame) {
4040
return TileOcclusionState::NotOccluded;
4141
}
4242

@@ -71,9 +71,9 @@ void CesiumViewExtension::BeginRenderViewFamily(
7171
// Recycle the current occlusion results.
7272
for (SceneViewOcclusionResults& occlusionResults :
7373
_currentOcclusionResults.occlusionResultsByView) {
74-
occlusionResults.PrimitiveOcclusionHistorySet.Reset();
75-
_recycledOcclusionHistorySets.Enqueue(
76-
std::move(occlusionResults.PrimitiveOcclusionHistorySet));
74+
occlusionResults.PrimitiveOcclusionResults.Reset();
75+
_recycledOcclusionResultSets.Enqueue(
76+
std::move(occlusionResults.PrimitiveOcclusionResults));
7777
}
7878
_currentOcclusionResults = {};
7979

@@ -121,19 +121,21 @@ void CesiumViewExtension::PostRenderViewFamily_RenderThread(
121121
// Do we actually need the view?
122122
occlusionResults.pView = pView;
123123

124-
if (!_recycledOcclusionHistorySets.IsEmpty()) {
124+
if (!_recycledOcclusionResultSets.IsEmpty()) {
125125
// Recycle a previously allocated occlusion history set, if one is
126126
// available.
127-
occlusionResults.PrimitiveOcclusionHistorySet =
128-
std::move(*_recycledOcclusionHistorySets.Peek());
129-
_recycledOcclusionHistorySets.Pop();
130-
occlusionResults.PrimitiveOcclusionHistorySet.Append(
131-
pViewState->PrimitiveOcclusionHistorySet);
127+
occlusionResults.PrimitiveOcclusionResults =
128+
std::move(*_recycledOcclusionResultSets.Peek());
129+
_recycledOcclusionResultSets.Pop();
132130
} else {
133131
// If no previously-allocated set exists, just allocate a new one. It
134132
// will be recycled later.
135-
occlusionResults.PrimitiveOcclusionHistorySet =
136-
pViewState->PrimitiveOcclusionHistorySet;
133+
}
134+
135+
occlusionResults.PrimitiveOcclusionResults.Reserve(
136+
pViewState->PrimitiveOcclusionHistorySet.Num());
137+
for (const auto& element : pViewState->PrimitiveOcclusionHistorySet) {
138+
occlusionResults.PrimitiveOcclusionResults.Emplace(element);
137139
}
138140

139141
// Unreal will not execute occlusion queries that get frustum culled in a
@@ -147,7 +149,7 @@ void CesiumViewExtension::PostRenderViewFamily_RenderThread(
147149
if (pView->bIsViewInfo && pScene != nullptr) {
148150
const FViewInfo* pViewInfo = static_cast<const FViewInfo*>(pView);
149151
const FSceneBitArray& visibility = pViewInfo->PrimitiveVisibilityMap;
150-
auto& occlusion = occlusionResults.PrimitiveOcclusionHistorySet;
152+
auto& occlusion = occlusionResults.PrimitiveOcclusionResults;
151153

152154
const uint32 PrimitiveCount = pScene->Primitives.Num();
153155
for (uint32 i = 0; i < PrimitiveCount; ++i) {
@@ -159,21 +161,18 @@ void CesiumViewExtension::PostRenderViewFamily_RenderThread(
159161
if (pSceneInfo == nullptr)
160162
continue;
161163

162-
const FPrimitiveOcclusionHistory* pHistory =
163-
occlusion.Find(FPrimitiveOcclusionHistoryKey(
164-
pSceneInfo->PrimitiveComponentId,
165-
0));
166-
if (!pHistory ||
167-
pHistory->LastConsideredTime < pViewState->LastRenderTime) {
164+
const PrimitiveOcclusionResult* pOcclusionResult =
165+
occlusion.Find(pSceneInfo->PrimitiveComponentId);
166+
if (!pOcclusionResult || pOcclusionResult->LastConsideredTime <
167+
pViewState->LastRenderTime) {
168168
// No valid occlusion history for this culled primitive, so create
169169
// it.
170-
FPrimitiveOcclusionHistory historyEntry{};
171-
historyEntry.PrimitiveId = pSceneInfo->PrimitiveComponentId;
172-
historyEntry.LastConsideredTime = pViewState->LastRenderTime;
173-
historyEntry.LastPixelsPercentage = 0.0f;
174-
historyEntry.WasOccludedLastFrame = true;
175-
historyEntry.OcclusionStateWasDefiniteLastFrame = true;
176-
occlusion.Add(std::move(historyEntry));
170+
occlusion.Emplace(PrimitiveOcclusionResult(
171+
pSceneInfo->PrimitiveComponentId,
172+
pViewState->LastRenderTime,
173+
0.0f,
174+
true,
175+
true));
177176
}
178177
}
179178
}

Source/CesiumRuntime/Private/CesiumViewExtension.h

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,56 @@ class ACesium3DTileset;
1616
class CesiumViewExtension : public FSceneViewExtensionBase {
1717
private:
1818
// Occlusion results for a single view.
19+
struct PrimitiveOcclusionResult {
20+
PrimitiveOcclusionResult(
21+
const FPrimitiveComponentId primitiveId,
22+
float lastConsideredTime,
23+
float lastPixelsPercentage,
24+
bool occlusionStateWasDefiniteLastFrame,
25+
bool wasOccludedLastFrame)
26+
: PrimitiveId(primitiveId),
27+
LastConsideredTime(lastConsideredTime),
28+
LastPixelsPercentage(lastPixelsPercentage),
29+
OcclusionStateWasDefiniteLastFrame(
30+
occlusionStateWasDefiniteLastFrame),
31+
WasOccludedLastFrame(wasOccludedLastFrame) {}
32+
33+
PrimitiveOcclusionResult(const FPrimitiveOcclusionHistory& renderer)
34+
: PrimitiveId(renderer.PrimitiveId),
35+
LastConsideredTime(renderer.LastConsideredTime),
36+
LastPixelsPercentage(renderer.LastPixelsPercentage),
37+
OcclusionStateWasDefiniteLastFrame(
38+
renderer.OcclusionStateWasDefiniteLastFrame),
39+
WasOccludedLastFrame(renderer.WasOccludedLastFrame) {}
40+
41+
FPrimitiveComponentId PrimitiveId;
42+
float LastConsideredTime;
43+
float LastPixelsPercentage;
44+
bool OcclusionStateWasDefiniteLastFrame;
45+
bool WasOccludedLastFrame;
46+
};
47+
48+
// Defines how PrimitiveOcclusionResult is stored in a TSet
49+
struct PrimitiveOcclusionResultKeyFuncs
50+
: BaseKeyFuncs<PrimitiveOcclusionResult, FPrimitiveComponentId> {
51+
typedef FPrimitiveComponentId KeyInitType;
52+
53+
static KeyInitType GetSetKey(const PrimitiveOcclusionResult& Element) {
54+
return Element.PrimitiveId;
55+
}
56+
57+
static bool Matches(KeyInitType A, KeyInitType B) { return A == B; }
58+
59+
static uint32 GetKeyHash(KeyInitType Key) {
60+
return GetTypeHash(Key.PrimIDValue);
61+
}
62+
};
63+
64+
// The occlusion results for a single view.
1965
struct SceneViewOcclusionResults {
2066
const FSceneView* pView = nullptr;
21-
TSet<FPrimitiveOcclusionHistory, FPrimitiveOcclusionHistoryKeyFuncs>
22-
PrimitiveOcclusionHistorySet{};
67+
TSet<PrimitiveOcclusionResult, PrimitiveOcclusionResultKeyFuncs>
68+
PrimitiveOcclusionResults{};
2369
};
2470

2571
// A collection of occlusion results by view.
@@ -35,13 +81,13 @@ class CesiumViewExtension : public FSceneViewExtensionBase {
3581
// thread.
3682
TQueue<AggregatedOcclusionUpdate, EQueueMode::Spsc> _occlusionResultsQueue;
3783

38-
// A queue to recycle the previously-allocated occlusion history sets. The
84+
// A queue to recycle the previously-allocated occlusion result sets. The
3985
// game thread recycles the sets by moving them into the queue and sending
4086
// them back to the render thread.
4187
TQueue<
42-
TSet<FPrimitiveOcclusionHistory, FPrimitiveOcclusionHistoryKeyFuncs>,
88+
TSet<PrimitiveOcclusionResult, PrimitiveOcclusionResultKeyFuncs>,
4389
EQueueMode::Spsc>
44-
_recycledOcclusionHistorySets;
90+
_recycledOcclusionResultSets;
4591

4692
// The last known frame number. This is used to determine when an occlusion
4793
// results aggregation is complete.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cesium-unreal",
3-
"version": "1.16.1",
3+
"version": "1.16.2",
44
"description": "Cesium for Unreal",
55
"main": "index.js",
66
"directories": {

0 commit comments

Comments
 (0)