Skip to content

Commit

Permalink
Sort of working again after reorg.
Browse files Browse the repository at this point in the history
But raster overlays don't work, and there appears to be an sRGB problem.
  • Loading branch information
kring committed Sep 30, 2024
1 parent efe384a commit 8b0bcdc
Show file tree
Hide file tree
Showing 11 changed files with 943 additions and 779 deletions.
4 changes: 2 additions & 2 deletions Source/CesiumRuntime/Private/Cesium3DTileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ class UnrealResourcePreparer
const Cesium3DTilesSelection::TileContent& content = tile.getContent();
const Cesium3DTilesSelection::TileRenderContent* pRenderContent =
content.getRenderContent();
if (pRenderContent) {
if (pMainThreadRendererResources != nullptr && pRenderContent != nullptr) {
UCesiumGltfComponent* pGltfContent =
reinterpret_cast<UCesiumGltfComponent*>(
pRenderContent->getRenderResources());
Expand Down Expand Up @@ -978,7 +978,7 @@ class UnrealResourcePreparer
UCesiumGltfComponent* pGltfContent =
reinterpret_cast<UCesiumGltfComponent*>(
pRenderContent->getRenderResources());
if (pGltfContent) {
if (pMainThreadRendererResources != nullptr && pGltfContent != nullptr) {
pGltfContent->DetachRasterTile(
tile,
rasterTile,
Expand Down
17 changes: 9 additions & 8 deletions Source/CesiumRuntime/Private/CesiumGltfComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "CesiumFeatureIdSet.h"
#include "CesiumGltfPointsComponent.h"
#include "CesiumGltfPrimitiveComponent.h"
#include "CesiumGltfTextures.h"
#include "CesiumMaterialUserData.h"
#include "CesiumRasterOverlays.h"
#include "CesiumRuntime.h"
Expand Down Expand Up @@ -400,22 +401,22 @@ struct ColorVisitor {
template <class T>
static TUniquePtr<CesiumTextureUtility::LoadedTextureResult> loadTexture(
CesiumGltf::Model& model,
const std::optional<T>& gltfTexture,
const std::optional<T>& gltfTextureInfo,
bool sRGB) {
if (!gltfTexture || gltfTexture.value().index < 0 ||
gltfTexture.value().index >= model.textures.size()) {
if (gltfTexture && gltfTexture.value().index >= 0) {
if (!gltfTextureInfo || gltfTextureInfo.value().index < 0 ||
gltfTextureInfo.value().index >= model.textures.size()) {
if (gltfTextureInfo && gltfTextureInfo.value().index >= 0) {
UE_LOG(
LogCesium,
Warning,
TEXT("Texture index must be less than %d, but is %d"),
model.textures.size(),
gltfTexture.value().index);
gltfTextureInfo.value().index);
}
return nullptr;
}

int32_t textureIndex = gltfTexture.value().index;
int32_t textureIndex = gltfTextureInfo.value().index;
CesiumGltf::Texture& texture = model.textures[textureIndex];
return loadTextureFromModelAnyThreadPart(model, texture, sRGB);
}
Expand Down Expand Up @@ -1061,7 +1062,7 @@ std::string constrainLength(const std::string& s, const size_t maxLength) {
}

/**
* @brief Create an FName from the given strings.
* @brief CreateNew an FName from the given strings.
*
* This will combine the prefix and the suffix and create an FName.
* If the string would be longer than the given length, then
Expand Down Expand Up @@ -2238,7 +2239,7 @@ loadModelAnyThreadPart(
const CesiumGeospatial::Ellipsoid& ellipsoid) {
TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::loadModelAnyThreadPart)

return createMipMapsForAllTextures(asyncSystem, *options.pModel)
return CesiumGltfTextures::createInWorkerThread(asyncSystem, *options.pModel)
.thenInWorkerThread(
[transform, ellipsoid, options = std::move(options)]()
-> UCesiumGltfComponent::CreateOffGameThreadResult {
Expand Down
70 changes: 8 additions & 62 deletions Source/CesiumRuntime/Private/CesiumGltfTextures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "CesiumRuntime.h"
#include "CesiumTextureResource.h"
#include "CesiumTextureUtility.h"
#include "ExtensionImageCesiumUnreal.h"
#include <CesiumGltf/AccessorView.h>
#include <CesiumGltf/AttributeSemantics.h>
#include <CesiumGltf/Model.h>
Expand Down Expand Up @@ -36,7 +37,7 @@ SharedFuture<void> createTextureInLoadThread(

} // namespace

/*static*/ CesiumAsync::Future<void> CesiumGltfTextures::createInLoadThread(
/*static*/ CesiumAsync::Future<void> CesiumGltfTextures::createInWorkerThread(
const CesiumAsync::AsyncSystem& asyncSystem,
CesiumGltf::Model& model) {
// This array is parallel to model.images and indicates whether each image
Expand Down Expand Up @@ -183,39 +184,6 @@ bool doesTextureUseMipmaps(const Model& gltf, const Texture& texture) {
}
}

struct ExtensionUnrealTextureResource {
static inline constexpr const char* TypeName =
"ExtensionUnrealTextureResource";
static inline constexpr const char* ExtensionName =
"PRIVATE_unreal_texture_resource";

ExtensionUnrealTextureResource() {}

TSharedPtr<FCesiumTextureResourceBase> pTextureResource = nullptr;
std::optional<CesiumAsync::SharedFuture<void>> createFuture = std::nullopt;
};

std::mutex textureResourceMutex;

// Returns a Future that will resolve when the image is loaded. It _may_ also
// return a Promise, in which case the calling thread is responsible for doing
// the loading and should resolve the Promise when it's done.
std::pair<SharedFuture<void>, std::optional<Promise<void>>>
getOrCreateImageFuture(const AsyncSystem& asyncSystem, Image& image) {
std::scoped_lock lock(textureResourceMutex);

ExtensionUnrealTextureResource& extension =
image.cesium->addExtension<ExtensionUnrealTextureResource>();
if (extension.createFuture) {
// Another thread is already working on this image.
return {*extension.createFuture, std::nullopt};
} else {
// This thread will work on this image.
Promise<void> promise = asyncSystem.createPromise<void>();
return {promise.getFuture().share(), promise};
}
}

SharedFuture<void> createTextureInLoadThread(
const AsyncSystem& asyncSystem,
Model& gltf,
Expand All @@ -233,35 +201,13 @@ SharedFuture<void> createTextureInLoadThread(
check(pTexture->source >= 0 && pTexture->source < imageNeedsMipmaps.size());
bool needsMips = imageNeedsMipmaps[pTexture->source];

auto [future, maybePromise] = getOrCreateImageFuture(asyncSystem, *pImage);
if (!maybePromise) {
// Another thread is already loading this image.
return future;
}

// Proceed to load the image in this thread.
ImageCesium& cesium = *pImage->cesium;

if (needsMips && !cesium.pixelData.empty()) {
std::optional<std::string> errorMessage =
CesiumGltfReader::GltfReader::generateMipMaps(cesium);
if (errorMessage) {
UE_LOG(
LogCesium,
Warning,
TEXT("%s"),
UTF8_TO_TCHAR(errorMessage->c_str()));
}
}

CesiumTextureUtility::loadTextureFromModelAnyThreadPart(
gltf,
*pTexture,
sRGB);

maybePromise->resolve();
const ExtensionImageCesiumUnreal& extension = ExtensionImageCesiumUnreal::GetOrCreate(
asyncSystem,
*pImage->cesium,
needsMips,
std::nullopt);

return future;
return extension.getFuture();
}

} // namespace
2 changes: 1 addition & 1 deletion Source/CesiumRuntime/Private/CesiumGltfTextures.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CesiumGltfTextures {
* Creates all of the textures that are required by the given glTF, and adds
* `ExtensionUnrealTexture` to each.
*/
static CesiumAsync::Future<void> createInLoadThread(
static CesiumAsync::Future<void> createInWorkerThread(
const CesiumAsync::AsyncSystem& asyncSystem,
CesiumGltf::Model& model);
};
Loading

0 comments on commit 8b0bcdc

Please sign in to comment.