Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/hotfix-1.16' into hotfix-1.16-ue5
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Aug 4, 2022
2 parents 60ae940 + 6e87128 commit 91ba717
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 41 deletions.
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Change Log

### v1.16.2 - 2022-08-04

##### Fixes :wrench:

- Fixed a bug that caused a crash in Unreal Engine 4.26 when enabling the experimental tileset occlusion culling feature.

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.

### v1.16.1 - 2022-08-01

##### Fixes :wrench:
Expand Down
4 changes: 2 additions & 2 deletions CesiumForUnreal.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 31,
"VersionName": "1.16.1",
"Version": 32,
"VersionName": "1.16.2",
"FriendlyName": "Cesium for Unreal",
"Description": "Unlock the 3D geospatial ecosystem in Unreal Engine with real-world 3D content and a high accuracy full-scale WGS84 globe.",
"Category": "Geospatial",
Expand Down
63 changes: 31 additions & 32 deletions Source/CesiumRuntime/Private/CesiumViewExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ TileOcclusionState CesiumViewExtension::getPrimitiveOcclusionState(

for (const SceneViewOcclusionResults& viewOcclusionResults :
_currentOcclusionResults.occlusionResultsByView) {
const FPrimitiveOcclusionHistory* pHistory =
viewOcclusionResults.PrimitiveOcclusionHistorySet.Find(
FPrimitiveOcclusionHistoryKey(id, 0));
const PrimitiveOcclusionResult* pOcclusionResult =
viewOcclusionResults.PrimitiveOcclusionResults.Find(id);

if (pHistory && pHistory->LastConsideredTime >= frameTimeCutoff) {
if (!pHistory->OcclusionStateWasDefiniteLastFrame) {
if (pOcclusionResult &&
pOcclusionResult->LastConsideredTime >= frameTimeCutoff) {
if (!pOcclusionResult->OcclusionStateWasDefiniteLastFrame) {
return TileOcclusionState::OcclusionUnavailable;
}

if (previouslyOccluded) {
if (pHistory->LastPixelsPercentage > 0.01f) {
if (pOcclusionResult->LastPixelsPercentage > 0.01f) {
return TileOcclusionState::NotOccluded;
}
} else if (!pHistory->WasOccludedLastFrame) {
} else if (!pOcclusionResult->WasOccludedLastFrame) {
return TileOcclusionState::NotOccluded;
}

Expand Down Expand Up @@ -71,9 +71,9 @@ void CesiumViewExtension::BeginRenderViewFamily(
// Recycle the current occlusion results.
for (SceneViewOcclusionResults& occlusionResults :
_currentOcclusionResults.occlusionResultsByView) {
occlusionResults.PrimitiveOcclusionHistorySet.Reset();
_recycledOcclusionHistorySets.Enqueue(
std::move(occlusionResults.PrimitiveOcclusionHistorySet));
occlusionResults.PrimitiveOcclusionResults.Reset();
_recycledOcclusionResultSets.Enqueue(
std::move(occlusionResults.PrimitiveOcclusionResults));
}
_currentOcclusionResults = {};

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

if (!_recycledOcclusionHistorySets.IsEmpty()) {
if (!_recycledOcclusionResultSets.IsEmpty()) {
// Recycle a previously allocated occlusion history set, if one is
// available.
occlusionResults.PrimitiveOcclusionHistorySet =
std::move(*_recycledOcclusionHistorySets.Peek());
_recycledOcclusionHistorySets.Pop();
occlusionResults.PrimitiveOcclusionHistorySet.Append(
pViewState->PrimitiveOcclusionHistorySet);
occlusionResults.PrimitiveOcclusionResults =
std::move(*_recycledOcclusionResultSets.Peek());
_recycledOcclusionResultSets.Pop();
} else {
// If no previously-allocated set exists, just allocate a new one. It
// will be recycled later.
occlusionResults.PrimitiveOcclusionHistorySet =
pViewState->PrimitiveOcclusionHistorySet;
}

occlusionResults.PrimitiveOcclusionResults.Reserve(
pViewState->PrimitiveOcclusionHistorySet.Num());
for (const auto& element : pViewState->PrimitiveOcclusionHistorySet) {
occlusionResults.PrimitiveOcclusionResults.Emplace(element);
}

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

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

const FPrimitiveOcclusionHistory* pHistory =
occlusion.Find(FPrimitiveOcclusionHistoryKey(
pSceneInfo->PrimitiveComponentId,
0));
if (!pHistory ||
pHistory->LastConsideredTime < pViewState->LastRenderTime) {
const PrimitiveOcclusionResult* pOcclusionResult =
occlusion.Find(pSceneInfo->PrimitiveComponentId);
if (!pOcclusionResult || pOcclusionResult->LastConsideredTime <
pViewState->LastRenderTime) {
// No valid occlusion history for this culled primitive, so create
// it.
FPrimitiveOcclusionHistory historyEntry{};
historyEntry.PrimitiveId = pSceneInfo->PrimitiveComponentId;
historyEntry.LastConsideredTime = pViewState->LastRenderTime;
historyEntry.LastPixelsPercentage = 0.0f;
historyEntry.WasOccludedLastFrame = true;
historyEntry.OcclusionStateWasDefiniteLastFrame = true;
occlusion.Add(std::move(historyEntry));
occlusion.Emplace(PrimitiveOcclusionResult(
pSceneInfo->PrimitiveComponentId,
pViewState->LastRenderTime,
0.0f,
true,
true));
}
}
}
Expand Down
56 changes: 51 additions & 5 deletions Source/CesiumRuntime/Private/CesiumViewExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,56 @@ class ACesium3DTileset;
class CesiumViewExtension : public FSceneViewExtensionBase {
private:
// Occlusion results for a single view.
struct PrimitiveOcclusionResult {
PrimitiveOcclusionResult(
const FPrimitiveComponentId primitiveId,
float lastConsideredTime,
float lastPixelsPercentage,
bool occlusionStateWasDefiniteLastFrame,
bool wasOccludedLastFrame)
: PrimitiveId(primitiveId),
LastConsideredTime(lastConsideredTime),
LastPixelsPercentage(lastPixelsPercentage),
OcclusionStateWasDefiniteLastFrame(
occlusionStateWasDefiniteLastFrame),
WasOccludedLastFrame(wasOccludedLastFrame) {}

PrimitiveOcclusionResult(const FPrimitiveOcclusionHistory& renderer)
: PrimitiveId(renderer.PrimitiveId),
LastConsideredTime(renderer.LastConsideredTime),
LastPixelsPercentage(renderer.LastPixelsPercentage),
OcclusionStateWasDefiniteLastFrame(
renderer.OcclusionStateWasDefiniteLastFrame),
WasOccludedLastFrame(renderer.WasOccludedLastFrame) {}

FPrimitiveComponentId PrimitiveId;
float LastConsideredTime;
float LastPixelsPercentage;
bool OcclusionStateWasDefiniteLastFrame;
bool WasOccludedLastFrame;
};

// Defines how PrimitiveOcclusionResult is stored in a TSet
struct PrimitiveOcclusionResultKeyFuncs
: BaseKeyFuncs<PrimitiveOcclusionResult, FPrimitiveComponentId> {
typedef FPrimitiveComponentId KeyInitType;

static KeyInitType GetSetKey(const PrimitiveOcclusionResult& Element) {
return Element.PrimitiveId;
}

static bool Matches(KeyInitType A, KeyInitType B) { return A == B; }

static uint32 GetKeyHash(KeyInitType Key) {
return GetTypeHash(Key.PrimIDValue);
}
};

// The occlusion results for a single view.
struct SceneViewOcclusionResults {
const FSceneView* pView = nullptr;
TSet<FPrimitiveOcclusionHistory, FPrimitiveOcclusionHistoryKeyFuncs>
PrimitiveOcclusionHistorySet{};
TSet<PrimitiveOcclusionResult, PrimitiveOcclusionResultKeyFuncs>
PrimitiveOcclusionResults{};
};

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

// A queue to recycle the previously-allocated occlusion history sets. The
// A queue to recycle the previously-allocated occlusion result sets. The
// game thread recycles the sets by moving them into the queue and sending
// them back to the render thread.
TQueue<
TSet<FPrimitiveOcclusionHistory, FPrimitiveOcclusionHistoryKeyFuncs>,
TSet<PrimitiveOcclusionResult, PrimitiveOcclusionResultKeyFuncs>,
EQueueMode::Spsc>
_recycledOcclusionHistorySets;
_recycledOcclusionResultSets;

// The last known frame number. This is used to determine when an occlusion
// results aggregation is complete.
Expand Down
2 changes: 1 addition & 1 deletion extern/cesium-native
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cesium-unreal",
"version": "1.16.1",
"version": "1.16.2",
"description": "Cesium for Unreal",
"main": "index.js",
"directories": {
Expand Down

0 comments on commit 91ba717

Please sign in to comment.