From 3a3319b8bb5e1785ff1347ae7a65212298ed9f8d Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Tue, 22 Feb 2022 14:33:31 -0500 Subject: [PATCH 1/9] initial progress dump --- .../Private/CesiumGltfComponent.cpp | 113 ++++++++++++++++-- .../CesiumGltfMeshVariantsComponent.cpp | 57 +++++++++ .../Private/CesiumGltfPrimitiveComponent.cpp | 1 + .../Private/CesiumGltfPrimitiveComponent.h | 4 + .../Private/CreateModelOptions.h | 22 ++++ .../Public/CesiumGltfMeshVariantsComponent.h | 80 +++++++++++++ extern/cesium-native | 2 +- 7 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp create mode 100644 Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 22c4b1cf3..da74db73f 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -11,6 +11,10 @@ #include "CesiumGltf/AccessorView.h" #include "CesiumGltf/ExtensionMeshPrimitiveExtFeatureMetadata.h" #include "CesiumGltf/ExtensionModelExtFeatureMetadata.h" +#include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" +#include "CesiumGltf/ExtensionModelMaxarMeshVariantsValue.h" +#include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" +#include "CesiumGltf/ExtensionNodeMaxarMeshVariantsMappingsValue.h" #include "CesiumGltf/TextureInfo.h" #include "CesiumGltfPrimitiveComponent.h" #include "CesiumMaterialUserData.h" @@ -40,6 +44,7 @@ #include #include #include +#include #if PHYSICS_INTERFACE_PHYSX #include "IPhysXCooking.h" @@ -61,8 +66,10 @@ struct LoadModelResult { FCesiumMetadataPrimitive Metadata{}; FStaticMeshRenderData* RenderData = nullptr; const CesiumGltf::Model* pModel = nullptr; + const CesiumGltf::Node* pNode = nullptr; const CesiumGltf::MeshPrimitive* pMeshPrimitive = nullptr; const CesiumGltf::Material* pMaterial = nullptr; + std::vector variants{}; glm::dmat4x4 transform{1.0}; #if PHYSICS_INTERFACE_PHYSX PxTriangleMesh* pCollisionMesh = nullptr; @@ -530,10 +537,11 @@ template static void loadPrimitive( std::vector& result, const CesiumGltf::Model& model, + const CesiumGltf::Node& node, const CesiumGltf::Mesh& mesh, const CesiumGltf::MeshPrimitive& primitive, const glm::dmat4x4& transform, - const CreateModelOptions& options, + const CreatePrimitiveOptions& options, const CesiumGltf::Accessor& positionAccessor, const CesiumGltf::AccessorView& positionView, const TIndexAccessor& indicesView) { @@ -640,7 +648,9 @@ static void loadPrimitive( Model::getSafe(&model.images, pTexture->source) != nullptr; } - bool needsTangents = hasNormalMap || options.alwaysIncludeTangents; + bool needsTangents = + hasNormalMap || + options.meshOptions.nodeOptions.modelOptions.alwaysIncludeTangents; bool hasTangents = false; auto tangentAccessorIt = primitive.attributes.find("TANGENT"); @@ -996,17 +1006,20 @@ static void loadPrimitive( LODResources.bHasAdjacencyInfo = false; primitiveResult.pModel = &model; + primitiveResult.pNode = &node; primitiveResult.pMeshPrimitive = &primitive; primitiveResult.RenderData = RenderData; primitiveResult.transform = transform; primitiveResult.pMaterial = &material; + primitiveResult.variants = options.meshOptions.variants; + section.MaterialIndex = 0; primitiveResult.pCollisionMesh = nullptr; #if PHYSICS_INTERFACE_PHYSX - if (options.pPhysXCooking) { + if (options.meshOptions.NodeOptions.modelOptions.pPhysXCooking) { CESIUM_TRACE("PhysX cook"); // TODO: use PhysX interface directly so we don't need to copy the // vertices (it takes a stride parameter). @@ -1054,10 +1067,11 @@ static void loadPrimitive( static void loadIndexedPrimitive( std::vector& result, const CesiumGltf::Model& model, + const CesiumGltf::Node& node, const CesiumGltf::Mesh& mesh, const CesiumGltf::MeshPrimitive& primitive, const glm::dmat4x4& transform, - const CreateModelOptions& options, + const CreatePrimitiveOptions& options, const CesiumGltf::Accessor& positionAccessor, const CesiumGltf::AccessorView& positionView) { const CesiumGltf::Accessor& indexAccessorGltf = @@ -1068,6 +1082,7 @@ static void loadIndexedPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1082,6 +1097,7 @@ static void loadIndexedPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1096,6 +1112,7 @@ static void loadIndexedPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1110,6 +1127,7 @@ static void loadIndexedPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1124,6 +1142,7 @@ static void loadIndexedPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1137,10 +1156,11 @@ static void loadIndexedPrimitive( static void loadPrimitive( std::vector& result, const CesiumGltf::Model& model, + const CesiumGltf::Node& node, const CesiumGltf::Mesh& mesh, const CesiumGltf::MeshPrimitive& primitive, const glm::dmat4x4& transform, - const CreateModelOptions& options) { + const CreatePrimitiveOptions& options) { CESIUM_TRACE("loadPrimitive"); auto positionAccessorIt = primitive.attributes.find("POSITION"); @@ -1168,6 +1188,7 @@ static void loadPrimitive( loadPrimitive( result, model, + node, mesh, primitive, transform, @@ -1179,6 +1200,7 @@ static void loadPrimitive( loadIndexedPrimitive( result, model, + node, mesh, primitive, transform, @@ -1191,14 +1213,15 @@ static void loadPrimitive( static void loadMesh( std::vector& result, const CesiumGltf::Model& model, + const CesiumGltf::Node& node, const CesiumGltf::Mesh& mesh, const glm::dmat4x4& transform, - const CreateModelOptions& options) { + const CreateMeshOptions& options) { CESIUM_TRACE("loadMesh"); for (const CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { - loadPrimitive(result, model, mesh, primitive, transform, options); + loadPrimitive(result, model, node, mesh, primitive, transform, options); } } @@ -1207,7 +1230,7 @@ static void loadNode( const CesiumGltf::Model& model, const CesiumGltf::Node& node, const glm::dmat4x4& transform, - const CreateModelOptions& options) { + const CreateNodeOptions& options) { static constexpr std::array identityMatrix = { 1.0, 0.0, @@ -1277,7 +1300,30 @@ static void loadNode( int meshId = node.mesh; if (meshId >= 0 && meshId < model.meshes.size()) { const CesiumGltf::Mesh& mesh = model.meshes[meshId]; - loadMesh(result, model, mesh, nodeTransform, options); + + const ExtensionModelMaxarMeshVariants* pModelVariants = + model.getExtension(); + const ExtensionNodeMaxarMeshVariants* pNodeVariants = + node.getExtension(); + + if (pModelVariants && pNodeVariants) { + for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : + pNodeVariants->mappings) { + if (mapping.mesh >= 0 && mapping.mesh < model.meshes.size()) { + CreateMeshOptions meshOptions = options; + meshOptions.variants = mapping.variants; + loadMesh( + result, + model, + node, + model.meshes[mapping.mesh], + nodeTransform, + meshOptions); + } + } + } else { + loadMesh(result, model, node, mesh, nodeTransform, options); + } } for (int childNodeId : node.children) { @@ -1498,12 +1544,13 @@ void SetWaterParameterValues( static void loadModelGameThreadPart( UCesiumGltfComponent* pGltf, + USceneComponent* pOutter, LoadModelResult& loadResult, const glm::dmat4x4& cesiumToUnrealTransform) { FName meshName = createSafeName(loadResult.name, ""); UCesiumGltfPrimitiveComponent* pMesh = - NewObject(pGltf, meshName); + NewObject(pOutter, meshName); pMesh->overlayTextureCoordinateIDToUVIndex = loadResult.overlayTextureCoordinateIDToUVIndex; pMesh->HighPrecisionNodeTransform = loadResult.transform; @@ -1725,9 +1772,53 @@ UCesiumGltfComponent::CreateOffGameThread( Gltf->CustomDepthParameters = CustomDepthParameters; + // TODO: can we refactor to have a hierarchical LoadResult? + // i.e. loadModelResult.nodeResults[i].meshResult.primitiveResults[j] + // This way loadModelResult.nodeResults[i] can contain node-level results + // like node variants. + std::map + uniqueNodeVariantsMap; + uniqueNodeVariantsMap.reserve(result.size()); + for (LoadModelResult& model : result) { - loadModelGameThreadPart(Gltf, model, cesiumToUnrealTransform); + const ExtensionModelMaxarMeshVariants* pModelVariants = + model.pModel->getExtension(); + const ExtensionNodeMaxarMeshVariants* pNodeVariants = + model.pModel->getExtension(); + + if (pModelVariants && pNodeVariants) { + auto uniqueNodeVariantsIt = uniqueNodeVariantsMap.find(pNodeVariants); + UCesiumGltfMeshVariantsComponent* pVariantsComponent; + if (uniqueNodeVariantsIt == uniqueNodeVariants.end()) { + // TODO: construct name during worker thread part? Will be unnecessary + // if we do the above suggested refactor. + std::string name = "glTF"; + + auto urlIt = model.pModel->extras.find("Cesium3DTiles_TileUrl"); + if (urlIt != model.pModel->end()) { + name = urlIt->second.getStringOrDefault("glTF"); + name = constrainLength(name, 256); + } + + name += "nodeVariant" + std::to_string(uniqueNodeVariantsMap.size()); + + pVariantsComponent = + NewObject(Gltf, name); + uniqueNodeVariantsMap.emplace(pNodeVariants, pVariantsComponent); + } else { + pVariantsComponent = uniqueNodeVariantsIt->second; + } + + loadModelGameThreadPart( + Gltf, + pVariantsComponent, + model, + cesiumToUnrealTransform); + } else { + loadModelGameThreadPart(Gltf, Gltf, model, cesiumToUnrealTransform); + } } + Gltf->SetVisibility(false, true); Gltf->SetCollisionEnabled(ECollisionEnabled::NoCollision); return Gltf; diff --git a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp new file mode 100644 index 000000000..035233c83 --- /dev/null +++ b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp @@ -0,0 +1,57 @@ + +#include "CesiumGltfMeshVariantsComponent.h" + +using namespace CesiumGltf; + +void UCesiumGltfMeshVariantsComponent::InitializeVariants( + const ExtensionModelMaxarMeshVariants& modelExtension, + const ExtensionNodeMaxarMeshVariants& nodeExtension) { + +} + +int32 UCesiumGltfMeshVariantsComponent::GetCurrentVariantIndex() const { + return this->_pCurrentVariant ? this->_pCurrentVariant->index : -1; +} + +const FString& UCesiumGltfMeshVariantsComponent::GetCurrentVariantName() const { + const static FString EMPTY_STRING = ""; + return this->_pCurrentVariant ? this->_pCurrentVariant->name : EMPTY_STRING; +} + +bool UCesiumGltfMeshVariantsComponent::SetVariantByIndex(int32 VariantIndex) { + if (VariantIndex < 0 || VariantIndex >= this->_variants.Num()) { + return false; + } + + this->_pCurrentVariant = &this->_variants[VariantIndex]; + return true; +} + +bool UCesiumGltfMeshVariantsComponent::SetVariantByName(const FString& Name) { + for (MeshVariant& variant : this->_variants) { + if (variant.name == Name) { + this->_pCurrentVariant = &variant; + return true; + } + } + + return false; +} + +void UCesiumGltfMeshVariantsComponent::BeginDestroy() { + this->_variants.Empty(); + super::BeginDestroy(); +} + +/*static*/ +UCesiumGltfMeshVariantsComponent* +UCesiumGltfMeshVariantsBlueprintLibrary::GetMeshVariantsComponent( + UPARAM(ref) UPrimitiveComponent* Primitive) { + UCesiumGltfPrimitiveComponent* pGltfPrimitive = + Cast(Primitive); + if (!IsValid(pGltfPrimitive)) { + return nullptr; + } + + return pGltfPrimitive->pMeshVariants; +} diff --git a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.cpp index c00d5e54a..5ed4a3fb0 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.cpp @@ -1,6 +1,7 @@ // Copyright 2020-2021 CesiumGS, Inc. and Contributors #include "CesiumGltfPrimitiveComponent.h" +#include "CesiumGltfMeshVariantsComponent.h" #include "CesiumLifetime.h" #include "CesiumMaterialUserData.h" #include "Engine/StaticMesh.h" diff --git a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h index 9171fafda..5895f773e 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h +++ b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h @@ -11,6 +11,8 @@ #include #include "CesiumGltfPrimitiveComponent.generated.h" +class UCesiumGltfMeshVariantsComponent; + UCLASS() class UCesiumGltfPrimitiveComponent : public UStaticMeshComponent { GENERATED_BODY() @@ -26,6 +28,8 @@ class UCesiumGltfPrimitiveComponent : public UStaticMeshComponent { const CesiumGltf::MeshPrimitive* pMeshPrimitive; + UCesiumGltfMeshVariantsComponent* pMeshVariants; + /** * The double-precision transformation matrix for this glTF node. */ diff --git a/Source/CesiumRuntime/Private/CreateModelOptions.h b/Source/CesiumRuntime/Private/CreateModelOptions.h index 7ad1b6836..526be9c5a 100644 --- a/Source/CesiumRuntime/Private/CreateModelOptions.h +++ b/Source/CesiumRuntime/Private/CreateModelOptions.h @@ -8,3 +8,25 @@ struct CreateModelOptions { IPhysXCooking* pPhysXCooking = nullptr; #endif }; + +struct CreateNodeOptions { + CreateModelOptions modelOptions{}; + + CreateNodeOptions(const CreateModelOptions& modelOptions_) + : modelOptions(modelOptions_) {} +}; + +struct CreateMeshOptions { + CreateNodeOptions nodeOptions{}; + std::vector variants{}; + + CreateMeshOptions(const CreateNodeOptions& nodeOptions_) + : nodeOptions(nodeOptions_) {} +}; + +struct CreatePrimitiveOptions { + CreateMeshOptions meshOptions{}; + + CreatePrimitiveOptions(const CreateMeshOptions& meshOptions_) + : meshOptions(meshOptions_) {} +}; diff --git a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h new file mode 100644 index 000000000..1032a6721 --- /dev/null +++ b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h @@ -0,0 +1,80 @@ +#pragma once + +#include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" +#include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" +#include "GenericPlatform/GenericPlatform.h" +#include "Components/SceneComponent.h" +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "CesiumGltfPrimitiveComponent.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include +#include "CesiumGltfMeshVariantsComponent.generated.h" + +namespace CesiumGltf { +struct Model; +struct Node; +} // namespace CesiumGltf + +namespace { +} // namespace + +UCLASS(BlueprintType) +class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponent { + GENERATED_BODY() + +public: + UCesiumGltfMeshVariantsComponent() = default; + virtual ~UCesiumGltfMeshVariantsComponent() = default; + + void InitializeVariants( + const CesiumGltf::ExtensionModelMaxarMeshVariants& modelExtension, + const CesiumGltf::ExtensionNodeMaxarMeshVariants& nodeExtension); + + UFUNCTION( + BlueprintCallable, + BlueprintPure, + Category = "Cesium|MeshVariants") + int32 GetCurrentVariantIndex() const; + + UFUNCTION( + BlueprintCallable, + BlueprintPure, + Category = "Cesium|MeshVariants") + const FString& GetCurrentVariantName() const; + + UFUNCTION( + BlueprintCallable, + Category = "Cesium|MeshVariants") + bool SetVariantByIndex(int32 VariantIndex); + + UFUNCTION( + BlueprintCallable, + Category = "Cesium|MeshVariants") + bool SetVariantByName(const FString& Name); + + virtual void BeginDestroy() override; + +private: + struct MeshVariant { + FString name; + int32 index; + std::vector meshPrimitives; + }; + + TArray _variants; + MeshVariant* _pCurrentVariant; + + friend UCesiumGltfMeshVariantsBlueprintLibrary; +}; + +UCLASS() +class CESIUMRUNTIME_API UCesiumGltfMeshVariantsBlueprintLibrary + : public UBlueprintFunctionLibrary { + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Cesium|MeshVariants") + static UCesiumGltfMeshVariantsComponent* + GetMeshVariantsComponent(UPARAM(ref) UPrimitiveComponent* Primitive); +}; diff --git a/extern/cesium-native b/extern/cesium-native index 0d60faa14..966aba608 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit 0d60faa141cdfc4101232a5c8c995b9567910590 +Subproject commit 966aba6089a8c11e129d0ce4ee597fe16ff968cb From ec6d32e3a1999c7176329b1090c4732d6086dcb2 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Tue, 22 Feb 2022 23:27:07 -0500 Subject: [PATCH 2/9] another broken progress dump before refactoring CesiumGltfComponent.cpp --- .../Private/CesiumGltfComponent.cpp | 68 ++++++++++++++++++- .../Public/CesiumGltfMeshVariantsComponent.h | 11 ++- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index da74db73f..22ee3c904 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #if PHYSICS_INTERFACE_PHYSX #include "IPhysXCooking.h" @@ -67,6 +67,7 @@ struct LoadModelResult { FStaticMeshRenderData* RenderData = nullptr; const CesiumGltf::Model* pModel = nullptr; const CesiumGltf::Node* pNode = nullptr; + const CesiumGltf::Mesh* pMesh = nullptr; const CesiumGltf::MeshPrimitive* pMeshPrimitive = nullptr; const CesiumGltf::Material* pMaterial = nullptr; std::vector variants{}; @@ -1542,7 +1543,7 @@ void SetWaterParameterValues( loadResult.waterMaskScale)); } -static void loadModelGameThreadPart( +static UCesiumGltfPrimitiveComponent* loadModelGameThreadPart( UCesiumGltfComponent* pGltf, USceneComponent* pOutter, LoadModelResult& loadResult, @@ -1724,6 +1725,8 @@ static void loadModelGameThreadPart( // pMesh->bDrawMeshCollisionIfSimple = true; pMesh->SetupAttachment(pGltf); pMesh->RegisterComponent(); + + return pMesh; } namespace { @@ -1780,6 +1783,67 @@ UCesiumGltfComponent::CreateOffGameThread( uniqueNodeVariantsMap; uniqueNodeVariantsMap.reserve(result.size()); + // This logic assumes the loaded primitives are sorted by node and then by mesh. + // This should be the case due to the way the glTF is recursed and the loaded + // primitives list is built. + if (!result.empty()) { + const ExtensionModelMaxarMeshVariants* pModelVariants = + result[0].pModel->getExtension(); + if (pModelVariants) { + const Node* pCurrentNode = nullptr; + const ExtensionNodeMaxarMeshVariants* pCurrentNodeVariants = nullptr; + const Mesh* pCurrentMesh = nullptr; + UCesiumGltfMeshVariantsComponent* pCurrentVariantsComponent = nullptr; + uint32_t nodeVariantCount = 0; + + // Reaggregates mesh from primitives. + std::vector mesh; + + for (LoadModelResult& model : result) { + if (model.pNode != pCurrentNode) { + // This is a new node + + pCurrentNode = model.pNode; + pCurrentNodeVariants = + pCurrentNode->getExtension(); + + if (pCurrentNodeVariants) { + std::string name = "glTF"; + + auto urlIt = model.pModel->extras.find("Cesium3DTiles_TileUrl"); + if (urlIt != model.pModel->end()) { + name = urlIt->second.getStringOrDefault("glTF"); + name = constrainLength(name, 256); + } + + name += "nodeVariant" + std::to_string(nodeVariantCount++); + + pCurrentVariantsComponent = + NewObject( + Gltf, + createSafeName(name, "")); + } else { + pCurrentVariantsComponent = nullptr; + } + } + + if (pCurrentVariantsComponent) { + if (model.pMesh != pCurrentMesh) { + pCurrentMesh = model.pMesh; + + pCurrentVariantsComponent->AddMesh() + } + + + } else { + loadModelGameThreadPart(Gltf, Gltf, model, cesiumToUnrealTransform); + } + } + } + } + + + for (LoadModelResult& model : result) { const ExtensionModelMaxarMeshVariants* pModelVariants = model.pModel->getExtension(); diff --git a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h index 1032a6721..67f6eecdb 100644 --- a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h +++ b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h @@ -8,6 +8,7 @@ #include "Containers/Map.h" #include "CesiumGltfPrimitiveComponent.h" #include "Kismet/BlueprintFunctionLibrary.h" +#include #include #include "CesiumGltfMeshVariantsComponent.generated.h" @@ -27,6 +28,8 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen UCesiumGltfMeshVariantsComponent() = default; virtual ~UCesiumGltfMeshVariantsComponent() = default; + void addVariant(std::vector) + void InitializeVariants( const CesiumGltf::ExtensionModelMaxarMeshVariants& modelExtension, const CesiumGltf::ExtensionNodeMaxarMeshVariants& nodeExtension); @@ -59,10 +62,14 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen struct MeshVariant { FString name; int32 index; - std::vector meshPrimitives; }; - TArray _variants; + struct MeshVariantMapping { + std::vector variants; + std::vector mesh; + }; + + TArray _variantMappings; MeshVariant* _pCurrentVariant; friend UCesiumGltfMeshVariantsBlueprintLibrary; From 6459b95c5117c22d5f59fa874ba178fac0bdb510 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Thu, 3 Mar 2022 11:52:41 -0500 Subject: [PATCH 3/9] expand visibility logic to show / hide tiles to take into account node variants also added new functionality for variants --- .../CesiumRuntime/Private/Cesium3DTileset.cpp | 31 +++-- .../Private/CesiumGltfComponent.cpp | 34 +++++- .../Private/CesiumGltfComponent.h | 4 + .../CesiumGltfMeshVariantsComponent.cpp | 115 +++++++++++++++++- .../Public/CesiumGltfMeshVariantsComponent.h | 39 +++--- 5 files changed, 181 insertions(+), 42 deletions(-) diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 0e8a52fff..9266c2426 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -513,8 +513,7 @@ void ACesium3DTileset::OnConstruction(const FTransform& Transform) { for (UCesiumGltfComponent* pGltf : gltfComponents) { if (pGltf && IsValid(pGltf) && pGltf->IsVisible()) { - pGltf->SetVisibility(false, true); - pGltf->SetCollisionEnabled(ECollisionEnabled::NoCollision); + pGltf->HideGltf(); } } } @@ -1389,8 +1388,7 @@ void hideTilesToNoLongerRender( UCesiumGltfComponent* Gltf = static_cast(pTile->getRendererResources()); if (Gltf && Gltf->IsVisible()) { - Gltf->SetVisibility(false, true); - Gltf->SetCollisionEnabled(ECollisionEnabled::NoCollision); + Gltf->HideGltf(); } else { // TODO: why is this happening? UE_LOG( @@ -1411,9 +1409,14 @@ void hideTilesToNoLongerRender( */ void applyActorCollisionSettings( const FBodyInstance& BodyInstance, - UCesiumGltfComponent* Gltf) { + USceneComponent* Component) { + + if (!Component) { + return; + } + UCesiumGltfPrimitiveComponent* PrimitiveComponent = - static_cast(Gltf->GetChildComponent(0)); + Cast(Component); if (PrimitiveComponent != nullptr) { if (PrimitiveComponent->GetCollisionObjectType() != BodyInstance.GetObjectType()) { @@ -1426,6 +1429,11 @@ void applyActorCollisionSettings( PrimitiveComponent->SetCollisionResponseToChannels(responseContainer); } } + + // Recursively apply collision settings to children. + for (USceneComponent* pChildComponent : Component->GetAttachChildren()) { + applyActorCollisionSettings(BodyInstance, pChildComponent); + } } } // namespace @@ -1504,14 +1512,6 @@ void ACesium3DTileset::showTilesToRender( continue; } - // That looks like some reeeally entertaining debug session...: - // const Cesium3DTilesSelection::TileID& id = pTile->getTileID(); - // const CesiumGeometry::QuadtreeTileID* pQuadtreeID = - // std::get_if(&id); if (!pQuadtreeID || - // pQuadtreeID->level != 14 || pQuadtreeID->x != 5503 || pQuadtreeID->y != - // 11626) { continue; - //} - UCesiumGltfComponent* Gltf = static_cast(pTile->getRendererResources()); if (!Gltf) { @@ -1545,8 +1545,7 @@ void ACesium3DTileset::showTilesToRender( } if (!Gltf->IsVisible()) { - Gltf->SetVisibility(true, true); - Gltf->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + Gltf->ShowGltf(); } } } diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 28f12fca4..64dfb1c4a 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -2006,8 +2006,7 @@ UCesiumGltfComponent::CreateOffGameThread( } } - Gltf->SetVisibility(false, true); - Gltf->SetCollisionEnabled(ECollisionEnabled::NoCollision); + HideGltf(); return Gltf; } @@ -2039,6 +2038,37 @@ UCesiumGltfComponent::~UCesiumGltfComponent() { UE_LOG(LogCesium, VeryVerbose, TEXT("~UCesiumGltfComponent")); } +void UCesiumGltfComponent::ShowGltf() { + if (!this->GetVisibleFlag()) { + this->SetVisibleFlag(true); + this->OnVisibilityChanged(); + } + + for (USceneComponent* pComponent : this->GetAttachChildren()) { + UCesiumGltfPrimitiveComponent* pPrimitive = + Cast(pComponent); + UCesiumGltfMeshVariantComponent* pVariant = + Cast(pComponent); + + if (pPrimitive && !pPrimitive->IsVisible()) { + pPrimitive->SetVisibility(true, true); + pPrimitive->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + } + + if (pVariant && !pVariant->IsVisible()) { + pVariant->ShowCurrentVariant(); + } + } +} + +void UCesiumGltfComponent::HideGltf() { + this->SetVisibility(false, true); + + // TODO: check if this is recursive, do descendent components automatically + // get set to NoCollision after this call? + this->SetCollisionEnabled(ECollisionEnabled::NoCollision); +} + void UCesiumGltfComponent::UpdateTransformFromCesium( const glm::dmat4& cesiumToUnrealTransform) { for (USceneComponent* pSceneComponent : this->GetAttachChildren()) { diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.h b/Source/CesiumRuntime/Private/CesiumGltfComponent.h index 03e48cdea..0169f1058 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.h +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.h @@ -90,6 +90,10 @@ class UCesiumGltfComponent : public USceneComponent { CesiumTextureUtility::EncodedMetadata EncodedMetadata; + void ShowGltf(); + + void HideGltf(); + void UpdateTransformFromCesium(const glm::dmat4& CesiumToUnrealTransform); void AttachRasterTile( diff --git a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp index 035233c83..7b04a8039 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp @@ -1,12 +1,59 @@ #include "CesiumGltfMeshVariantsComponent.h" +#include "CesiumGltfPrimitiveComponent.h" +#include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" +#include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" +#include using namespace CesiumGltf; -void UCesiumGltfMeshVariantsComponent::InitializeVariants( - const ExtensionModelMaxarMeshVariants& modelExtension, - const ExtensionNodeMaxarMeshVariants& nodeExtension) { +bool UCesiumGltfMeshVariantsComponent::InitializeVariants( + const ExtensionModelMaxarMeshVariants* pModelExtension, + const ExtensionNodeMaxarMeshVariants* pNodeExtension) { + if (pModelExtension && pNodeExtension) { + return false; + } + + this->_pModelMeshVariants = pModelExtension; + this->_pNodeMeshVariants = pNodeExtension; + + if (this->_pModelMeshVariants->defaultProperty < 0 || + this->_pModelMeshVariants->defaultProperty >= + this->_pModelMeshVariants->variants.size()) { + return false; + } + + this->_currentVariantIndex = + static_cast(this->_pModelMeshVariants->defaultProperty); + + return true; +} + +void AddMesh(uint32_t meshIndex, std::vector&& mesh) { + assert(this->_pModelMeshVariants != nullptr); + assert(this->_pNodeMeshVariants != nullptr); + assert(this->_currentVariantIndex != -1); + assert(this->_meshes.find(meshIndex) == this->_meshes.end()); + + auto meshIt = this->_meshes.emplace(meshIndex, std::move(mesh)).first; + // Find the mapping for this mesh. + for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : + this->_pNodeMeshVariants->mappings) { + if (mapping.mesh == meshIndex) { + // Check if this mapping contains the current variant. + for (int32_t variantIndex : mapping.variants) { + if (variantIndex == this->_currentVariantIndex) { + // This should be the only visible mesh for now. + // TODO: SetVisible + for (UCesiumGltfPrimitiveComponent* pPrimitive : meshIt->second) { + + } + } + } + break; + } + } } int32 UCesiumGltfMeshVariantsComponent::GetCurrentVariantIndex() const { @@ -38,6 +85,68 @@ bool UCesiumGltfMeshVariantsComponent::SetVariantByName(const FString& Name) { return false; } +static void showMesh(const std::vector& mesh) { + for (UCesiumGltfPrimitiveComponent* pPrimitive : mesh) { + if (pPrimitive && !pPrimitive->IsVisible()) { + pPrimitive->SetVisibility(true, true); + pPrimitive->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + } + } +} + +static void hideMesh(const std::vector& mesh) { + for (UCesiumGltfPrimitiveComponent* pPrimitive : mesh) { + if (pPrimitive && pPrimitive->IsVisible()) { + pPrimitive->SetVisibility(false, true); + pPrimitive->SetCollisionEnabled(ECollisionEnabled::NoCollision); + } + } +} + +void ShowCurrentVariant() { + assert(this->_pModelMeshVariants != nullptr); + assert(this->_pNodeMeshVariants != nullptr); + assert(this->_currentVariantIndex != -1); + + if (!this->GetVisibleFlag()) { + this->SetVisibleFlag(bNewVisibility); + this->OnVisibilityChanged(); + } + + // Only the currently selected mesh variant should be set visible. + bool visibleMeshFound = false; + for (auto& meshIt : this->_meshes) { + if (visibleMeshFound) { + // We already found the visible mesh, so hide this mesh. + hideMesh(meshIt.second); + } else { + // Need to check if this mesh contains the current variant. + // Find the mapping for this mesh. + for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : + this->_pNodeMeshVariants->mappings) { + if (mapping.mesh == meshIt.first) { + // We found the mesh's mapping. + // Check if this mesh's mapping contains the current variant. + for (int32_t variantIndex : mapping.variants) { + if (variantIndex == this->_currentVariantIndex) { + visibleMeshFound = true; + break; + } + } + // Already found this mesh's mapping. + break; + } + } + + if (visibleMeshFound) { + showMesh(meshit.second); + } else { + hideMesh(meshIt.second); + } + } + } +} + void UCesiumGltfMeshVariantsComponent::BeginDestroy() { this->_variants.Empty(); super::BeginDestroy(); diff --git a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h index 67f6eecdb..3538bef5f 100644 --- a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h +++ b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h @@ -1,24 +1,24 @@ #pragma once -#include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" -#include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" #include "GenericPlatform/GenericPlatform.h" #include "Components/SceneComponent.h" #include "Containers/Array.h" #include "Containers/Map.h" -#include "CesiumGltfPrimitiveComponent.h" #include "Kismet/BlueprintFunctionLibrary.h" #include +#include #include #include "CesiumGltfMeshVariantsComponent.generated.h" namespace CesiumGltf { struct Model; struct Node; +struct ExtensionModelMaxarMeshVariants; +struct ExtensionNodeMaxarMeshVariants; +struct ExtensionModelMaxarMeshVariantsValue; } // namespace CesiumGltf -namespace { -} // namespace +class UCesiumGltfPrimitiveComponent; UCLASS(BlueprintType) class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponent { @@ -28,11 +28,11 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen UCesiumGltfMeshVariantsComponent() = default; virtual ~UCesiumGltfMeshVariantsComponent() = default; - void addVariant(std::vector) + bool InitializeVariants( + const CesiumGltf::ExtensionModelMaxarMeshVariants* pModelExtension, + const CesiumGltf::ExtensionNodeMaxarMeshVariants* pNodeExtension); - void InitializeVariants( - const CesiumGltf::ExtensionModelMaxarMeshVariants& modelExtension, - const CesiumGltf::ExtensionNodeMaxarMeshVariants& nodeExtension); + void AddMesh(uint32_t meshIndex, std::vector&& mesh); UFUNCTION( BlueprintCallable, @@ -56,21 +56,18 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen Category = "Cesium|MeshVariants") bool SetVariantByName(const FString& Name); + void ShowCurrentVariant(); + virtual void BeginDestroy() override; private: - struct MeshVariant { - FString name; - int32 index; - }; - - struct MeshVariantMapping { - std::vector variants; - std::vector mesh; - }; - - TArray _variantMappings; - MeshVariant* _pCurrentVariant; + + const CesiumGltf::ExtensionModelMaxarMeshVariants* _pModelMeshVariants; + const CesiumGltf::ExtensionNodeMaxarMeshVariants* _pNodeMeshVariants; + + int32_t _currentVariantIndex = -1; + + std::unordered_map> _meshes; friend UCesiumGltfMeshVariantsBlueprintLibrary; }; From efc161662c5b39913cd873a10acc7f8742796b5c Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Thu, 3 Mar 2022 14:03:25 -0500 Subject: [PATCH 4/9] Fully hook up mesh variants component into gltf component loading / creation --- .../Private/CesiumGltfComponent.cpp | 82 ++++++++++++++----- .../CesiumGltfMeshVariantsComponent.cpp | 70 +++++++++------- Source/CesiumRuntime/Private/LoadGltfResult.h | 4 + .../Public/CesiumGltfMeshVariantsComponent.h | 16 ++-- 4 files changed, 114 insertions(+), 58 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 64dfb1c4a..18795ed5d 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -20,6 +20,7 @@ #include "CesiumGltf/ExtensionNodeMaxarMeshVariantsMappingsValue.h" #include "CesiumGltf/PropertyType.h" #include "CesiumGltf/TextureInfo.h" +#include "CesiumGltfMeshVariantsComponent.h" #include "CesiumGltfPrimitiveComponent.h" #include "CesiumMaterialUserData.h" #include "CesiumMetadataFeatureTable.h" @@ -1266,8 +1267,15 @@ static void loadPrimitive( } else { loadIndexedPrimitive( result, + transform, + options, + *pPositionAccessor, + positionView); + } +} + static void loadMesh( - std::optional& result, + LoadMeshResult& result, const glm::dmat4x4& transform, const CreateMeshOptions& options) { @@ -1276,12 +1284,10 @@ static void loadMesh( const Model& model = *options.pNodeOptions->pModelOptions->pModel; const Mesh& mesh = *options.pMesh; - result = LoadMeshResult(); - for (const MeshPrimitive& primitive : mesh.primitives) { - CreatePrimitiveOptions primitiveOptions = {&options, &*result, &primitive}; + CreatePrimitiveOptions primitiveOptions = {&options, &result, &primitive}; loadPrimitive( - result->primitiveResults.emplace_back(), + result.primitiveResults.emplace_back(), transform, primitiveOptions); } @@ -1362,10 +1368,26 @@ static void loadNode( nodeTransform * translation * glm::dmat4(rotationQuat) * scale; } - int meshId = node.mesh; - if (meshId >= 0 && meshId < model.meshes.size()) { - CreateMeshOptions meshOptions = {&options, &result, &model.meshes[meshId]}; - loadMesh(result.meshResult, nodeTransform, meshOptions); + result.pVariantsExtension = + node.getExtension(); + if (result.pVariantsExtension) { + result.meshVariantsResults.reserve(result.pVariantsExtension->mappings.size()); + for (ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : + result.pVariantsExtension->mappings) { + if (mapping.mesh >= 0 && mapping.mesh < model.meshes.size()) { + CreateMeshOptions meshOptions = + {&options, &result, &model.meshes[mapping.mesh]}; + LoadMeshResult& meshResult = result.meshVariantsResults.emplace_back(); + loadMesh(meshResult, nodeTransform, meshOptions); + } + } + } else { + int meshId = node.mesh; + if (meshId >= 0 && meshId < model.meshes.size()) { + CreateMeshOptions meshOptions = {&options, &result, &model.meshes[meshId]}; + result.meshResult = LoadMeshResult{}; + loadMesh(*result.meshResult, nodeTransform, meshOptions); + } } for (int childNodeId : node.children) { @@ -1441,6 +1463,9 @@ static void loadModelAnyThreadPart( result.EncodedMetadata = encodeMetadataAnyThreadPart(result.Metadata); } + result.pVariantsExtension = + model.getExtension(); + glm::dmat4x4 rootTransform = transform; { @@ -1743,8 +1768,10 @@ static void SetMetadataParameterValues( } } -static void loadPrimitiveGameThreadPart( +static UCesiumGltfPrimitiveComponent* loadPrimitiveGameThreadPart( + // TODO: I don't think this pGltf is needed after a few simplifications UCesiumGltfComponent* pGltf, + USceneComponent* pOutter, LoadPrimitiveResult& loadResult, const glm::dmat4x4& cesiumToUnrealTransform) { @@ -1948,7 +1975,7 @@ static void loadPrimitiveGameThreadPart( // pMesh->bDrawMeshCollisionIfComplex = true; // pMesh->bDrawMeshCollisionIfSimple = true; - pMesh->SetupAttachment(pGltf); + pMesh->SetupAttachment(pOutter); pMesh->RegisterComponent(); return pMesh; @@ -1974,12 +2001,6 @@ UCesiumGltfComponent::CreateOffGameThread( HalfConstructedReal* pReal = static_cast(pHalfConstructed.get()); - // TODO: was this a common case before? - // (This code checked if there were no loaded primitives in the model) - // if (result.size() == 0) { - // return nullptr; - // } - UCesiumGltfComponent* Gltf = NewObject(pParentActor); Gltf->SetUsingAbsoluteLocation(true); Gltf->SetFlags(RF_Transient | RF_DuplicateTransient | RF_TextExportTransient); @@ -1998,15 +2019,36 @@ UCesiumGltfComponent::CreateOffGameThread( Gltf->CustomDepthParameters = CustomDepthParameters; encodeMetadataGameThreadPart(Gltf->EncodedMetadata); + int32 nodeIndex = 0; for (LoadNodeResult& node : pReal->loadModelResult.nodeResults) { - if (node.meshResult) { + UCesiumMeshVariants* pVariants = + UCesiumMeshVariants::CreateMeshVariantsComponent( + Gltf, + // TODO: create better name, maybe during worker thread part instead? + "node" + FString::FromInt(nodeIndex) + "_variant", + pReal->loadModelResult.pVariantsExtension, + node.pVariantsExtension); + + if (pVariants) { + for (LoadMeshResult& meshResult : node.meshVariantsResults) { + std::vector mesh; + mesh.reserve(meshResult.primitiveResults.size()); + + for (LoadPrimitiveResult& primitive : meshResult.primitiveResults) { + mesh.push_back( + loadPrimitiveGameThreadPart(Gltf, pVariants, primitive, cesiumToUnrealTransform)); + } + + pVariants->AddMesh(std::move(mesh)); + } + } else if (node.meshResult) { for (LoadPrimitiveResult& primitive : node.meshResult->primitiveResults) { - loadPrimitiveGameThreadPart(Gltf, primitive, cesiumToUnrealTransform); + loadPrimitiveGameThreadPart(Gltf, Gltf, primitive, cesiumToUnrealTransform); } } } - HideGltf(); + Gltf->HideGltf(); return Gltf; } diff --git a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp index 7b04a8039..3a89f9195 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp @@ -7,26 +7,32 @@ using namespace CesiumGltf; -bool UCesiumGltfMeshVariantsComponent::InitializeVariants( +/*static*/ UCesiumGltfMeshVariantsComponent* +UCesiumGltfMeshVariantsComponent::CreateMeshVariantsComponent( + USceneComponent* pOutter, + const FString& name, const ExtensionModelMaxarMeshVariants* pModelExtension, const ExtensionNodeMaxarMeshVariants* pNodeExtension) { - if (pModelExtension && pNodeExtension) { - return false; - } - this->_pModelMeshVariants = pModelExtension; - this->_pNodeMeshVariants = pNodeExtension; - - if (this->_pModelMeshVariants->defaultProperty < 0 || - this->_pModelMeshVariants->defaultProperty >= - this->_pModelMeshVariants->variants.size()) { - return false; + if (!pModelExtension || !pNodeExtension || + pModelExtension->defaultProperty < 0 || + pModelExtension->defaultProperty >= pModelExtension->variants.size()) { + return nullptr; } - this->_currentVariantIndex = + UCesiumMeshVariantsComponent* pVariantsComponent = + NewObject(pOutter, name); + + pVariantsComponent->_pModelMeshVariants = pModelExtension; + pVariantsComponent->_pNodeMeshVariants = pNodeExtension; + pVariantsComponent->_currentVariantIndex = static_cast(this->_pModelMeshVariants->defaultProperty); - return true; + pVariantsComponent->SetMobility(EComponentMobility::Movable); + pVariantsComponent->SetupAttachment(pOutter); + pVariantsComponent->RegisterComponent(); + + return pVariantsComponent; } void AddMesh(uint32_t meshIndex, std::vector&& mesh) { @@ -56,13 +62,14 @@ void AddMesh(uint32_t meshIndex, std::vector&& m } } -int32 UCesiumGltfMeshVariantsComponent::GetCurrentVariantIndex() const { - return this->_pCurrentVariant ? this->_pCurrentVariant->index : -1; -} +FString UCesiumGltfMeshVariantsComponent::GetCurrentVariantName() const { + if (this->_pModelMeshVariants && this->_currentVariantIndex != -1) { + return + FString(UTF8_TO_TCHAR( + this->_pModelMeshVariants->variants[this->_currentVariantIndex].name.c_str())); + } -const FString& UCesiumGltfMeshVariantsComponent::GetCurrentVariantName() const { - const static FString EMPTY_STRING = ""; - return this->_pCurrentVariant ? this->_pCurrentVariant->name : EMPTY_STRING; + return ""; } bool UCesiumGltfMeshVariantsComponent::SetVariantByIndex(int32 VariantIndex) { @@ -70,15 +77,21 @@ bool UCesiumGltfMeshVariantsComponent::SetVariantByIndex(int32 VariantIndex) { return false; } - this->_pCurrentVariant = &this->_variants[VariantIndex]; + this->_currentVariantIndex = VariantIndex; + ShowCurrentVariant(); return true; } bool UCesiumGltfMeshVariantsComponent::SetVariantByName(const FString& Name) { - for (MeshVariant& variant : this->_variants) { - if (variant.name == Name) { - this->_pCurrentVariant = &variant; - return true; + if (this->_pModelMeshVariants) { + for (size_t i = 0; i < this->_pModelMeshVariants->variants.size(); ++i) { + const std::string& variantName = + this->_pModelMeshVariants->variants[i].name; + if (Name == FString(UTF8_TO_TCHAR(variantName.c_str()))) { + this->_currentVariantIndex = static_cast(i); + ShowCurrentVariant(); + return true; + } } } @@ -103,13 +116,13 @@ static void hideMesh(const std::vector& mesh) { } } -void ShowCurrentVariant() { +void UCesiumGltfMeshVariantsComponent::ShowCurrentVariant() { assert(this->_pModelMeshVariants != nullptr); assert(this->_pNodeMeshVariants != nullptr); assert(this->_currentVariantIndex != -1); if (!this->GetVisibleFlag()) { - this->SetVisibleFlag(bNewVisibility); + this->SetVisibleFlag(true); this->OnVisibilityChanged(); } @@ -147,11 +160,6 @@ void ShowCurrentVariant() { } } -void UCesiumGltfMeshVariantsComponent::BeginDestroy() { - this->_variants.Empty(); - super::BeginDestroy(); -} - /*static*/ UCesiumGltfMeshVariantsComponent* UCesiumGltfMeshVariantsBlueprintLibrary::GetMeshVariantsComponent( diff --git a/Source/CesiumRuntime/Private/LoadGltfResult.h b/Source/CesiumRuntime/Private/LoadGltfResult.h index a0ae4ca5d..ea19d3025 100644 --- a/Source/CesiumRuntime/Private/LoadGltfResult.h +++ b/Source/CesiumRuntime/Private/LoadGltfResult.h @@ -16,6 +16,7 @@ #include #include #include +#include #if PHYSICS_INTERFACE_PHYSX #include "IPhysXCooking.h" @@ -67,11 +68,14 @@ struct LoadMeshResult { struct LoadNodeResult { std::optional meshResult = std::nullopt; + std::vector meshVariantsResults; + const ExtensionNodeMaxarMeshVariants* pVariantsExtension = nullptr; }; struct LoadModelResult { std::vector nodeResults{}; FCesiumMetadataModel Metadata{}; CesiumTextureUtility::EncodedMetadata EncodedMetadata{}; + const ExtensionModelMaxarMeshVariants* pVariantsExtension = nullptr; }; } // namespace LoadGltfResult diff --git a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h index 3538bef5f..6d1e18031 100644 --- a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h +++ b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h @@ -28,23 +28,21 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen UCesiumGltfMeshVariantsComponent() = default; virtual ~UCesiumGltfMeshVariantsComponent() = default; - bool InitializeVariants( - const CesiumGltf::ExtensionModelMaxarMeshVariants* pModelExtension, - const CesiumGltf::ExtensionNodeMaxarMeshVariants* pNodeExtension); - void AddMesh(uint32_t meshIndex, std::vector&& mesh); UFUNCTION( BlueprintCallable, BlueprintPure, Category = "Cesium|MeshVariants") - int32 GetCurrentVariantIndex() const; + int32 GetCurrentVariantIndex() const { + return this->_currentVariantIndex; + } UFUNCTION( BlueprintCallable, BlueprintPure, Category = "Cesium|MeshVariants") - const FString& GetCurrentVariantName() const; + FString GetCurrentVariantName() const; UFUNCTION( BlueprintCallable, @@ -58,7 +56,11 @@ class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponen void ShowCurrentVariant(); - virtual void BeginDestroy() override; + static UCesiumGltfMeshVariantsComponent* CreateMeshVariantsComponent( + USceneComponent* pOutter, + const FString& name, + const CesiumGltf::ExtensionModelMaxarMeshVariants* pModelExtension, + const CesiumGltf::ExtensionNodeMaxarMeshVariants* pNodeExtension); private: From f94a0ac5f35b8ade4156c8a631b82302fb09722f Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Thu, 3 Mar 2022 15:28:25 -0500 Subject: [PATCH 5/9] small fixes, compiling --- .../CesiumRuntime/Private/Cesium3DTileset.cpp | 4 +- .../Private/CesiumGltfComponent.cpp | 82 +++++++++++-------- .../CesiumGltfMeshVariantsComponent.cpp | 75 +++++++---------- Source/CesiumRuntime/Private/LoadGltfResult.h | 10 ++- .../Public/CesiumGltfMeshVariantsComponent.h | 49 +++++------ 5 files changed, 106 insertions(+), 114 deletions(-) diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 9266c2426..25bc02ca6 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -1410,7 +1410,7 @@ void hideTilesToNoLongerRender( void applyActorCollisionSettings( const FBodyInstance& BodyInstance, USceneComponent* Component) { - + if (!Component) { return; } @@ -1429,7 +1429,7 @@ void applyActorCollisionSettings( PrimitiveComponent->SetCollisionResponseToChannels(responseContainer); } } - + // Recursively apply collision settings to children. for (USceneComponent* pChildComponent : Component->GetAttachChildren()) { applyActorCollisionSettings(BodyInstance, pChildComponent); diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 18795ed5d..82f055baa 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -47,12 +47,12 @@ #include "StaticMeshResources.h" #include "UObject/ConstructorHelpers.h" #include "mikktspace.h" +#include #include #include #include #include #include -#include #if PHYSICS_INTERFACE_PHYSX #include "IPhysXCooking.h" @@ -1126,14 +1126,11 @@ static void loadPrimitive( #endif primitiveResult.pModel = &model; - primitiveResult.pNode = &node; primitiveResult.pMeshPrimitive = &primitive; primitiveResult.RenderData = RenderData; primitiveResult.transform = transform; primitiveResult.pMaterial = &material; - primitiveResult.variants = options.meshOptions.variants; - section.MaterialIndex = 0; primitiveResult.pCollisionMesh = nullptr; @@ -1368,23 +1365,30 @@ static void loadNode( nodeTransform * translation * glm::dmat4(rotationQuat) * scale; } - result.pVariantsExtension = + result.pVariantsExtension = node.getExtension(); if (result.pVariantsExtension) { - result.meshVariantsResults.reserve(result.pVariantsExtension->mappings.size()); - for (ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : + result.meshVariantsResults.reserve( + result.pVariantsExtension->mappings.size()); + for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : result.pVariantsExtension->mappings) { if (mapping.mesh >= 0 && mapping.mesh < model.meshes.size()) { - CreateMeshOptions meshOptions = - {&options, &result, &model.meshes[mapping.mesh]}; - LoadMeshResult& meshResult = result.meshVariantsResults.emplace_back(); - loadMesh(meshResult, nodeTransform, meshOptions); + CreateMeshOptions meshOptions = { + &options, + &result, + &model.meshes[mapping.mesh]}; + auto meshResultIt = + result.meshVariantsResults.emplace(mapping.mesh, LoadMeshResult{}); + loadMesh(meshResultIt.first->second, nodeTransform, meshOptions); } } } else { int meshId = node.mesh; if (meshId >= 0 && meshId < model.meshes.size()) { - CreateMeshOptions meshOptions = {&options, &result, &model.meshes[meshId]}; + CreateMeshOptions meshOptions = { + &options, + &result, + &model.meshes[meshId]}; result.meshResult = LoadMeshResult{}; loadMesh(*result.meshResult, nodeTransform, meshOptions); } @@ -1463,7 +1467,7 @@ static void loadModelAnyThreadPart( result.EncodedMetadata = encodeMetadataAnyThreadPart(result.Metadata); } - result.pVariantsExtension = + result.pVariantsExtension = model.getExtension(); glm::dmat4x4 rootTransform = transform; @@ -1499,11 +1503,12 @@ static void loadModelAnyThreadPart( for (const Mesh& mesh : model.meshes) { CreateNodeOptions dummyNodeOptions = {&options, &result, nullptr}; LoadNodeResult& dummyNodeResult = result.nodeResults.emplace_back(); + dummyNodeResult.meshResult = LoadMeshResult{}; CreateMeshOptions meshOptions = { &dummyNodeOptions, &dummyNodeResult, &mesh}; - loadMesh(dummyNodeResult.meshResult, rootTransform, meshOptions); + loadMesh(*dummyNodeResult.meshResult, rootTransform, meshOptions); } } } @@ -2021,31 +2026,42 @@ UCesiumGltfComponent::CreateOffGameThread( encodeMetadataGameThreadPart(Gltf->EncodedMetadata); int32 nodeIndex = 0; for (LoadNodeResult& node : pReal->loadModelResult.nodeResults) { - UCesiumMeshVariants* pVariants = - UCesiumMeshVariants::CreateMeshVariantsComponent( - Gltf, - // TODO: create better name, maybe during worker thread part instead? - "node" + FString::FromInt(nodeIndex) + "_variant", - pReal->loadModelResult.pVariantsExtension, - node.pVariantsExtension); - + UCesiumGltfMeshVariantsComponent* pVariants = + UCesiumGltfMeshVariantsComponent::CreateMeshVariantsComponent( + Gltf, + // TODO: create better name, maybe during worker thread part + // instead? + createSafeName("node" + std::to_string(nodeIndex) + "_variant", ""), + pReal->loadModelResult.pVariantsExtension, + node.pVariantsExtension); + if (pVariants) { - for (LoadMeshResult& meshResult : node.meshVariantsResults) { + for (auto& meshResult : node.meshVariantsResults) { std::vector mesh; - mesh.reserve(meshResult.primitiveResults.size()); - - for (LoadPrimitiveResult& primitive : meshResult.primitiveResults) { - mesh.push_back( - loadPrimitiveGameThreadPart(Gltf, pVariants, primitive, cesiumToUnrealTransform)); + mesh.reserve(meshResult.second.primitiveResults.size()); + + for (LoadPrimitiveResult& primitive : + meshResult.second.primitiveResults) { + mesh.push_back(loadPrimitiveGameThreadPart( + Gltf, + pVariants, + primitive, + cesiumToUnrealTransform)); } - pVariants->AddMesh(std::move(mesh)); + pVariants->AddMesh(meshResult.first, std::move(mesh)); } } else if (node.meshResult) { for (LoadPrimitiveResult& primitive : node.meshResult->primitiveResults) { - loadPrimitiveGameThreadPart(Gltf, Gltf, primitive, cesiumToUnrealTransform); + loadPrimitiveGameThreadPart( + Gltf, + Gltf, + primitive, + cesiumToUnrealTransform); } } + + ++nodeIndex; } Gltf->HideGltf(); @@ -2087,10 +2103,10 @@ void UCesiumGltfComponent::ShowGltf() { } for (USceneComponent* pComponent : this->GetAttachChildren()) { - UCesiumGltfPrimitiveComponent* pPrimitive = + UCesiumGltfPrimitiveComponent* pPrimitive = Cast(pComponent); - UCesiumGltfMeshVariantComponent* pVariant = - Cast(pComponent); + UCesiumGltfMeshVariantsComponent* pVariant = + Cast(pComponent); if (pPrimitive && !pPrimitive->IsVisible()) { pPrimitive->SetVisibility(true, true); diff --git a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp index 3a89f9195..18530fbe9 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp @@ -1,32 +1,33 @@ #include "CesiumGltfMeshVariantsComponent.h" -#include "CesiumGltfPrimitiveComponent.h" #include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" #include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" +#include "CesiumGltfPrimitiveComponent.h" +#include "UObject/UObjectGlobals.h" #include using namespace CesiumGltf; -/*static*/ UCesiumGltfMeshVariantsComponent* +/*static*/ UCesiumGltfMeshVariantsComponent* UCesiumGltfMeshVariantsComponent::CreateMeshVariantsComponent( USceneComponent* pOutter, - const FString& name, + const FName& name, const ExtensionModelMaxarMeshVariants* pModelExtension, const ExtensionNodeMaxarMeshVariants* pNodeExtension) { if (!pModelExtension || !pNodeExtension || - pModelExtension->defaultProperty < 0 || + pModelExtension->defaultProperty < 0 || pModelExtension->defaultProperty >= pModelExtension->variants.size()) { return nullptr; } - UCesiumMeshVariantsComponent* pVariantsComponent = - NewObject(pOutter, name); + UCesiumGltfMeshVariantsComponent* pVariantsComponent = + NewObject(pOutter, name); pVariantsComponent->_pModelMeshVariants = pModelExtension; pVariantsComponent->_pNodeMeshVariants = pNodeExtension; - pVariantsComponent->_currentVariantIndex = - static_cast(this->_pModelMeshVariants->defaultProperty); + pVariantsComponent->_currentVariantIndex = + static_cast(pModelExtension->defaultProperty); pVariantsComponent->SetMobility(EComponentMobility::Movable); pVariantsComponent->SetupAttachment(pOutter); @@ -35,45 +36,25 @@ UCesiumGltfMeshVariantsComponent::CreateMeshVariantsComponent( return pVariantsComponent; } -void AddMesh(uint32_t meshIndex, std::vector&& mesh) { - assert(this->_pModelMeshVariants != nullptr); - assert(this->_pNodeMeshVariants != nullptr); - assert(this->_currentVariantIndex != -1); - assert(this->_meshes.find(meshIndex) == this->_meshes.end()); - - auto meshIt = this->_meshes.emplace(meshIndex, std::move(mesh)).first; - - // Find the mapping for this mesh. - for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : - this->_pNodeMeshVariants->mappings) { - if (mapping.mesh == meshIndex) { - // Check if this mapping contains the current variant. - for (int32_t variantIndex : mapping.variants) { - if (variantIndex == this->_currentVariantIndex) { - // This should be the only visible mesh for now. - // TODO: SetVisible - for (UCesiumGltfPrimitiveComponent* pPrimitive : meshIt->second) { - - } - } - } - break; - } - } +void UCesiumGltfMeshVariantsComponent::AddMesh( + uint32_t meshIndex, + std::vector&& mesh) { + this->_meshes.emplace(meshIndex, std::move(mesh)); } FString UCesiumGltfMeshVariantsComponent::GetCurrentVariantName() const { if (this->_pModelMeshVariants && this->_currentVariantIndex != -1) { - return - FString(UTF8_TO_TCHAR( - this->_pModelMeshVariants->variants[this->_currentVariantIndex].name.c_str())); + return FString(UTF8_TO_TCHAR( + this->_pModelMeshVariants->variants[this->_currentVariantIndex] + .name.c_str())); } return ""; -} +} bool UCesiumGltfMeshVariantsComponent::SetVariantByIndex(int32 VariantIndex) { - if (VariantIndex < 0 || VariantIndex >= this->_variants.Num()) { + if (VariantIndex < 0 || + VariantIndex >= this->_pModelMeshVariants->variants.size()) { return false; } @@ -85,7 +66,7 @@ bool UCesiumGltfMeshVariantsComponent::SetVariantByIndex(int32 VariantIndex) { bool UCesiumGltfMeshVariantsComponent::SetVariantByName(const FString& Name) { if (this->_pModelMeshVariants) { for (size_t i = 0; i < this->_pModelMeshVariants->variants.size(); ++i) { - const std::string& variantName = + const std::string& variantName = this->_pModelMeshVariants->variants[i].name; if (Name == FString(UTF8_TO_TCHAR(variantName.c_str()))) { this->_currentVariantIndex = static_cast(i); @@ -94,7 +75,7 @@ bool UCesiumGltfMeshVariantsComponent::SetVariantByName(const FString& Name) { } } } - + return false; } @@ -120,7 +101,7 @@ void UCesiumGltfMeshVariantsComponent::ShowCurrentVariant() { assert(this->_pModelMeshVariants != nullptr); assert(this->_pNodeMeshVariants != nullptr); assert(this->_currentVariantIndex != -1); - + if (!this->GetVisibleFlag()) { this->SetVisibleFlag(true); this->OnVisibilityChanged(); @@ -136,7 +117,7 @@ void UCesiumGltfMeshVariantsComponent::ShowCurrentVariant() { // Need to check if this mesh contains the current variant. // Find the mapping for this mesh. for (const ExtensionNodeMaxarMeshVariantsMappingsValue& mapping : - this->_pNodeMeshVariants->mappings) { + this->_pNodeMeshVariants->mappings) { if (mapping.mesh == meshIt.first) { // We found the mesh's mapping. // Check if this mesh's mapping contains the current variant. @@ -152,7 +133,7 @@ void UCesiumGltfMeshVariantsComponent::ShowCurrentVariant() { } if (visibleMeshFound) { - showMesh(meshit.second); + showMesh(meshIt.second); } else { hideMesh(meshIt.second); } @@ -160,15 +141,15 @@ void UCesiumGltfMeshVariantsComponent::ShowCurrentVariant() { } } -/*static*/ +/*static*/ UCesiumGltfMeshVariantsComponent* UCesiumGltfMeshVariantsBlueprintLibrary::GetMeshVariantsComponent( UPARAM(ref) UPrimitiveComponent* Primitive) { - UCesiumGltfPrimitiveComponent* pGltfPrimitive = + UCesiumGltfPrimitiveComponent* pGltfPrimitive = Cast(Primitive); if (!IsValid(pGltfPrimitive)) { return nullptr; } - - return pGltfPrimitive->pMeshVariants; + + return pGltfPrimitive->pMeshVariants; } diff --git a/Source/CesiumRuntime/Private/LoadGltfResult.h b/Source/CesiumRuntime/Private/LoadGltfResult.h index ea19d3025..662003e2e 100644 --- a/Source/CesiumRuntime/Private/LoadGltfResult.h +++ b/Source/CesiumRuntime/Private/LoadGltfResult.h @@ -2,6 +2,8 @@ #pragma once +#include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" +#include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" #include "CesiumGltf/Material.h" #include "CesiumGltf/MeshPrimitive.h" #include "CesiumGltf/Model.h" @@ -68,14 +70,16 @@ struct LoadMeshResult { struct LoadNodeResult { std::optional meshResult = std::nullopt; - std::vector meshVariantsResults; - const ExtensionNodeMaxarMeshVariants* pVariantsExtension = nullptr; + std::unordered_map meshVariantsResults; + const CesiumGltf::ExtensionNodeMaxarMeshVariants* pVariantsExtension = + nullptr; }; struct LoadModelResult { std::vector nodeResults{}; FCesiumMetadataModel Metadata{}; CesiumTextureUtility::EncodedMetadata EncodedMetadata{}; - const ExtensionModelMaxarMeshVariants* pVariantsExtension = nullptr; + const CesiumGltf::ExtensionModelMaxarMeshVariants* pVariantsExtension = + nullptr; }; } // namespace LoadGltfResult diff --git a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h index 6d1e18031..1683deb59 100644 --- a/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h +++ b/Source/CesiumRuntime/Public/CesiumGltfMeshVariantsComponent.h @@ -1,9 +1,9 @@ #pragma once -#include "GenericPlatform/GenericPlatform.h" #include "Components/SceneComponent.h" #include "Containers/Array.h" #include "Containers/Map.h" +#include "GenericPlatform/GenericPlatform.h" #include "Kismet/BlueprintFunctionLibrary.h" #include #include @@ -21,55 +21,46 @@ struct ExtensionModelMaxarMeshVariantsValue; class UCesiumGltfPrimitiveComponent; UCLASS(BlueprintType) -class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent : public USceneComponent { +class CESIUMRUNTIME_API UCesiumGltfMeshVariantsComponent + : public USceneComponent { GENERATED_BODY() public: UCesiumGltfMeshVariantsComponent() = default; virtual ~UCesiumGltfMeshVariantsComponent() = default; - void AddMesh(uint32_t meshIndex, std::vector&& mesh); - - UFUNCTION( - BlueprintCallable, - BlueprintPure, - Category = "Cesium|MeshVariants") - int32 GetCurrentVariantIndex() const { - return this->_currentVariantIndex; - } - - UFUNCTION( - BlueprintCallable, - BlueprintPure, - Category = "Cesium|MeshVariants") - FString GetCurrentVariantName() const; - - UFUNCTION( - BlueprintCallable, - Category = "Cesium|MeshVariants") + void AddMesh( + uint32_t meshIndex, + std::vector&& mesh); + + UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Cesium|MeshVariants") + int32 GetCurrentVariantIndex() const { return this->_currentVariantIndex; } + + UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Cesium|MeshVariants") + FString GetCurrentVariantName() const; + + UFUNCTION(BlueprintCallable, Category = "Cesium|MeshVariants") bool SetVariantByIndex(int32 VariantIndex); - - UFUNCTION( - BlueprintCallable, - Category = "Cesium|MeshVariants") + + UFUNCTION(BlueprintCallable, Category = "Cesium|MeshVariants") bool SetVariantByName(const FString& Name); void ShowCurrentVariant(); static UCesiumGltfMeshVariantsComponent* CreateMeshVariantsComponent( USceneComponent* pOutter, - const FString& name, + const FName& name, const CesiumGltf::ExtensionModelMaxarMeshVariants* pModelExtension, const CesiumGltf::ExtensionNodeMaxarMeshVariants* pNodeExtension); private: - const CesiumGltf::ExtensionModelMaxarMeshVariants* _pModelMeshVariants; const CesiumGltf::ExtensionNodeMaxarMeshVariants* _pNodeMeshVariants; - int32_t _currentVariantIndex = -1; + int32_t _currentVariantIndex = -1; - std::unordered_map> _meshes; + std::unordered_map> + _meshes; friend UCesiumGltfMeshVariantsBlueprintLibrary; }; From b634ddca8ebf734f19cb70e002efe61fcf3e6882 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Thu, 3 Mar 2022 15:58:19 -0500 Subject: [PATCH 6/9] fix static method to get mesh variant component --- .../CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp | 3 ++- Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp index 18530fbe9..45715bc55 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfMeshVariantsComponent.cpp @@ -151,5 +151,6 @@ UCesiumGltfMeshVariantsBlueprintLibrary::GetMeshVariantsComponent( return nullptr; } - return pGltfPrimitive->pMeshVariants; + return Cast( + pGltfPrimitive->GetAttachParent()); } diff --git a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h index 57cb4170e..ab4a556db 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h +++ b/Source/CesiumRuntime/Private/CesiumGltfPrimitiveComponent.h @@ -31,8 +31,6 @@ class UCesiumGltfPrimitiveComponent : public UStaticMeshComponent { const CesiumGltf::MeshPrimitive* pMeshPrimitive; - UCesiumGltfMeshVariantsComponent* pMeshVariants; - /** * The double-precision transformation matrix for this glTF node. */ From 77213355e12fcb5d4d337451964b068adc8a2d50 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Mon, 21 Mar 2022 16:14:34 -0400 Subject: [PATCH 7/9] update native --- extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/cesium-native b/extern/cesium-native index 027fb29bc..c17a928c2 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit 027fb29bc506fd75951505b02e1f6038cc609398 +Subproject commit c17a928c2f9a987fdc92c4e2b6571ea6d401a73c From 3751c5934e320244b5265ad585f6587ded93e154 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Tue, 22 Mar 2022 01:19:42 -0400 Subject: [PATCH 8/9] merge fixes, compiling, probably some unneeded fixes --- .../CesiumRuntime/Private/Cesium3DTileset.cpp | 2 +- .../Private/CesiumGltfComponent.cpp | 19 +++++----- Source/CesiumRuntime/Private/LoadGltfResult.h | 36 +++++++++++++------ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 09fdcbfd4..f076c3539 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -585,7 +585,7 @@ class UnrealResourcePreparer pLoadThreadResult)); return UCesiumGltfComponent::CreateOnGameThread( this->_pActor, - std::move(pHalf), + MoveTemp(pHalf), _pActor->GetCesiumTilesetToUnrealRelativeWorldTransform(), this->_pActor->GetMaterial(), this->_pActor->GetWaterMaterial(), diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 1ada75463..8de5c86f9 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -99,7 +99,7 @@ namespace { class HalfConstructedReal : public UCesiumGltfComponent::HalfConstructed { public: virtual ~HalfConstructedReal() {} - LoadModelResult loadModelResult; + LoadModelResult loadModelResult{}; }; } // namespace @@ -1301,16 +1301,15 @@ static void loadMesh( const Model& model = *options.pNodeOptions->pModelOptions->pModel; const Mesh& mesh = *options.pMesh; - result = LoadMeshResult(); - result->primitiveResults.reserve(mesh.primitives.size()); + result.primitiveResults.reserve(mesh.primitives.size()); for (const CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { - CreatePrimitiveOptions primitiveOptions = {&options, &*result, &primitive}; - auto& primitiveResult = result->primitiveResults.emplace_back(); + CreatePrimitiveOptions primitiveOptions = {&options, &result, &primitive}; + auto& primitiveResult = result.primitiveResults.emplace_back(); loadPrimitive(primitiveResult, transform, primitiveOptions); // if it doesn't have render data, then it can't be loaded if (!primitiveResult.RenderData) { - result->primitiveResults.pop_back(); + result.primitiveResults.pop_back(); } } } @@ -1403,7 +1402,7 @@ static void loadNode( &result, &model.meshes[mapping.mesh]}; auto meshResultIt = - result.meshVariantsResults.emplace(mapping.mesh, LoadMeshResult{}); + result.meshVariantsResults.try_emplace(mapping.mesh); loadMesh(meshResultIt.first->second, nodeTransform, meshOptions); } } @@ -1414,7 +1413,7 @@ static void loadNode( &options, &result, &model.meshes[meshId]}; - result.meshResult = LoadMeshResult{}; + result.meshResult.emplace(); loadMesh(*result.meshResult, nodeTransform, meshOptions); } } @@ -1532,7 +1531,7 @@ static void loadModelAnyThreadPart( for (const Mesh& mesh : model.meshes) { CreateNodeOptions dummyNodeOptions = {&options, &result, nullptr}; LoadNodeResult& dummyNodeResult = result.nodeResults.emplace_back(); - dummyNodeResult.meshResult = LoadMeshResult{}; + dummyNodeResult.meshResult.emplace(); CreateMeshOptions meshOptions = { &dummyNodeOptions, &dummyNodeResult, @@ -2025,7 +2024,7 @@ UCesiumGltfComponent::CreateOffGameThread( auto pResult = MakeUnique(); loadModelAnyThreadPart(pResult->loadModelResult, Transform, Options); - return pResult; + return MoveTemp(pResult); } /*static*/ UCesiumGltfComponent* UCesiumGltfComponent::CreateOnGameThread( diff --git a/Source/CesiumRuntime/Private/LoadGltfResult.h b/Source/CesiumRuntime/Private/LoadGltfResult.h index 7108906cb..8f6f0389a 100644 --- a/Source/CesiumRuntime/Private/LoadGltfResult.h +++ b/Source/CesiumRuntime/Private/LoadGltfResult.h @@ -2,9 +2,9 @@ #pragma once +#include "CesiumEncodedMetadataUtility.h" #include "CesiumGltf/ExtensionModelMaxarMeshVariants.h" #include "CesiumGltf/ExtensionNodeMaxarMeshVariants.h" -#include "CesiumEncodedMetadataUtility.h" #include "CesiumGltf/Material.h" #include "CesiumGltf/MeshPrimitive.h" #include "CesiumGltf/Model.h" @@ -51,7 +51,7 @@ struct LoadPrimitiveResult { const CesiumGltf::Material* pMaterial = nullptr; glm::dmat4x4 transform{1.0}; #if PHYSICS_INTERFACE_PHYSX - TUniquePtr pCollisionMesh; + TUniquePtr pCollisionMesh = nullptr; FBodySetupUVInfo uvInfo{}; #else TSharedPtr @@ -59,13 +59,17 @@ struct LoadPrimitiveResult { #endif std::string name{}; - TUniquePtr baseColorTexture; + TUniquePtr baseColorTexture = + nullptr; TUniquePtr - metallicRoughnessTexture; - TUniquePtr normalTexture; - TUniquePtr emissiveTexture; - TUniquePtr occlusionTexture; - TUniquePtr waterMaskTexture; + metallicRoughnessTexture = nullptr; + TUniquePtr normalTexture = nullptr; + TUniquePtr emissiveTexture = + nullptr; + TUniquePtr occlusionTexture = + nullptr; + TUniquePtr waterMaskTexture = + nullptr; std::unordered_map textureCoordinateParameters; bool onlyLand = true; @@ -79,11 +83,20 @@ struct LoadPrimitiveResult { std::unordered_map textureCoordinateMap; }; +// TODO: which ones of these explicit constructors are actually needed?? struct LoadMeshResult { - std::vector primitiveResults{}; + LoadMeshResult() = default; + LoadMeshResult(const LoadMeshResult& result) = delete; + LoadMeshResult(LoadMeshResult&& result) = default; + + std::vector primitiveResults; }; struct LoadNodeResult { + LoadNodeResult() = default; + LoadNodeResult(const LoadNodeResult& result) = delete; + LoadNodeResult(LoadNodeResult&& result) = default; + std::optional meshResult = std::nullopt; std::unordered_map meshVariantsResults; const CesiumGltf::ExtensionNodeMaxarMeshVariants* pVariantsExtension = @@ -91,7 +104,10 @@ struct LoadNodeResult { }; struct LoadModelResult { - std::vector nodeResults{}; + LoadModelResult() = default; + LoadModelResult(const LoadModelResult& result) = delete; + + std::vector nodeResults; FCesiumMetadataModel Metadata{}; CesiumEncodedMetadataUtility::EncodedMetadata EncodedMetadata{}; const CesiumGltf::ExtensionModelMaxarMeshVariants* pVariantsExtension = From 8ac662345998c2e762bfd46bee19a1a7967fcfb2 Mon Sep 17 00:00:00 2001 From: Nithin Pranesh Date: Tue, 22 Mar 2022 10:38:04 -0400 Subject: [PATCH 9/9] fix georeferencing mesh variants --- Source/CesiumRuntime/Private/Cesium3DTileset.cpp | 8 ++++---- Source/CesiumRuntime/Private/CesiumGltfComponent.cpp | 11 ----------- Source/CesiumRuntime/Private/CesiumGltfComponent.h | 2 -- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index f076c3539..5ba0b6d7e 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -464,11 +464,11 @@ void ACesium3DTileset::UpdateTransformFromCesium() { const glm::dmat4& CesiumToUnreal = this->GetCesiumTilesetToUnrealRelativeWorldTransform(); - TArray gltfComponents; - this->GetComponents(gltfComponents); + TInlineComponentArray primitiveComponents( + this); - for (UCesiumGltfComponent* pGltf : gltfComponents) { - pGltf->UpdateTransformFromCesium(CesiumToUnreal); + for (UCesiumGltfPrimitiveComponent* pPrimitive : primitiveComponents) { + pPrimitive->UpdateTransformFromCesium(CesiumToUnreal); } } diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 8de5c86f9..a1419f404 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -2158,17 +2158,6 @@ void UCesiumGltfComponent::HideGltf() { this->SetCollisionEnabled(ECollisionEnabled::NoCollision); } -void UCesiumGltfComponent::UpdateTransformFromCesium( - const glm::dmat4& cesiumToUnrealTransform) { - for (USceneComponent* pSceneComponent : this->GetAttachChildren()) { - UCesiumGltfPrimitiveComponent* pPrimitive = - Cast(pSceneComponent); - if (pPrimitive) { - pPrimitive->UpdateTransformFromCesium(cesiumToUnrealTransform); - } - } -} - namespace { template diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.h b/Source/CesiumRuntime/Private/CesiumGltfComponent.h index 601f33bc7..0a16f6c6f 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.h +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.h @@ -94,8 +94,6 @@ class UCesiumGltfComponent : public USceneComponent { void HideGltf(); - void UpdateTransformFromCesium(const glm::dmat4& CesiumToUnrealTransform); - void AttachRasterTile( const Cesium3DTilesSelection::Tile& Tile, const Cesium3DTilesSelection::RasterOverlayTile& RasterTile,