Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MAXAR_mesh_variants #773

Open
wants to merge 14 commits into
base: ue4-main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions Source/CesiumRuntime/Private/Cesium3DTileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,11 +463,11 @@ void ACesium3DTileset::UpdateTransformFromCesium() {

const glm::dmat4& CesiumToUnreal =
this->GetCesiumTilesetToUnrealRelativeWorldTransform();
TArray<UCesiumGltfComponent*> gltfComponents;
this->GetComponents<UCesiumGltfComponent>(gltfComponents);
TInlineComponentArray<UCesiumGltfPrimitiveComponent*> primitiveComponents(
this);

for (UCesiumGltfComponent* pGltf : gltfComponents) {
pGltf->UpdateTransformFromCesium(CesiumToUnreal);
for (UCesiumGltfPrimitiveComponent* pPrimitive : primitiveComponents) {
pPrimitive->UpdateTransformFromCesium(CesiumToUnreal);
}
}

Expand Down Expand Up @@ -512,8 +512,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();
}
}
}
Expand Down Expand Up @@ -585,7 +584,7 @@ class UnrealResourcePreparer
pLoadThreadResult));
return UCesiumGltfComponent::CreateOnGameThread(
this->_pActor,
std::move(pHalf),
MoveTemp(pHalf),
_pActor->GetCesiumTilesetToUnrealRelativeWorldTransform(),
this->_pActor->GetMaterial(),
this->_pActor->GetWaterMaterial(),
Expand Down Expand Up @@ -1395,8 +1394,7 @@ void hideTilesToNoLongerRender(
UCesiumGltfComponent* Gltf =
static_cast<UCesiumGltfComponent*>(pTile->getRendererResources());
if (Gltf && Gltf->IsVisible()) {
Gltf->SetVisibility(false, true);
Gltf->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Gltf->HideGltf();
} else {
// TODO: why is this happening?
UE_LOG(
Expand All @@ -1417,9 +1415,14 @@ void hideTilesToNoLongerRender(
*/
void applyActorCollisionSettings(
const FBodyInstance& BodyInstance,
UCesiumGltfComponent* Gltf) {
USceneComponent* Component) {

if (!Component) {
return;
}

UCesiumGltfPrimitiveComponent* PrimitiveComponent =
static_cast<UCesiumGltfPrimitiveComponent*>(Gltf->GetChildComponent(0));
Cast<UCesiumGltfPrimitiveComponent>(Component);
if (PrimitiveComponent != nullptr) {
if (PrimitiveComponent->GetCollisionObjectType() !=
BodyInstance.GetObjectType()) {
Expand All @@ -1432,6 +1435,11 @@ void applyActorCollisionSettings(
PrimitiveComponent->SetCollisionResponseToChannels(responseContainer);
}
}

// Recursively apply collision settings to children.
for (USceneComponent* pChildComponent : Component->GetAttachChildren()) {
applyActorCollisionSettings(BodyInstance, pChildComponent);
}
}
} // namespace

Expand Down Expand Up @@ -1510,14 +1518,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<CesiumGeometry::QuadtreeTileID>(&id); if (!pQuadtreeID ||
// pQuadtreeID->level != 14 || pQuadtreeID->x != 5503 || pQuadtreeID->y !=
// 11626) { continue;
//}

UCesiumGltfComponent* Gltf =
static_cast<UCesiumGltfComponent*>(pTile->getRendererResources());
if (!Gltf) {
Expand Down Expand Up @@ -1551,8 +1551,7 @@ void ACesium3DTileset::showTilesToRender(
}

if (!Gltf->IsVisible()) {
Gltf->SetVisibility(true, true);
Gltf->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Gltf->ShowGltf();
}
}
}
Expand Down
145 changes: 113 additions & 32 deletions Source/CesiumRuntime/Private/CesiumGltfComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@
#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/PropertyType.h"
#include "CesiumGltf/TextureInfo.h"
#include "CesiumGltfMeshVariantsComponent.h"
#include "CesiumGltfPrimitiveComponent.h"
#include "CesiumMaterialUserData.h"
#include "CesiumRasterOverlays.h"
Expand All @@ -42,6 +47,7 @@
#include "StaticMeshResources.h"
#include "UObject/ConstructorHelpers.h"
#include "mikktspace.h"
#include <algorithm>
#include <cstddef>
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
Expand Down Expand Up @@ -93,7 +99,7 @@ namespace {
class HalfConstructedReal : public UCesiumGltfComponent::HalfConstructed {
public:
virtual ~HalfConstructedReal() {}
LoadModelResult loadModelResult;
LoadModelResult loadModelResult{};
};
} // namespace

Expand Down Expand Up @@ -1300,7 +1306,7 @@ static void loadPrimitive(
}

static void loadMesh(
std::optional<LoadMeshResult>& result,
LoadMeshResult& result,
const glm::dmat4x4& transform,
const CreateMeshOptions& options) {

Expand All @@ -1309,16 +1315,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();
}
}
}
Expand Down Expand Up @@ -1398,10 +1403,33 @@ 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<ExtensionNodeMaxarMeshVariants>();
if (result.pVariantsExtension) {
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]};
auto meshResultIt =
result.meshVariantsResults.try_emplace(mapping.mesh);
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]};
result.meshResult.emplace();
loadMesh(*result.meshResult, nodeTransform, meshOptions);
}
}

for (int childNodeId : node.children) {
Expand Down Expand Up @@ -1481,6 +1509,9 @@ static void loadModelAnyThreadPart(
}
}

result.pVariantsExtension =
model.getExtension<ExtensionModelMaxarMeshVariants>();

glm::dmat4x4 rootTransform = transform;

{
Expand Down Expand Up @@ -1514,11 +1545,12 @@ static void loadModelAnyThreadPart(
for (const Mesh& mesh : model.meshes) {
CreateNodeOptions dummyNodeOptions = {&options, &result, nullptr};
LoadNodeResult& dummyNodeResult = result.nodeResults.emplace_back();
dummyNodeResult.meshResult.emplace();
CreateMeshOptions meshOptions = {
&dummyNodeOptions,
&dummyNodeResult,
&mesh};
loadMesh(dummyNodeResult.meshResult, rootTransform, meshOptions);
loadMesh(*dummyNodeResult.meshResult, rootTransform, meshOptions);
}
}
}
Expand Down Expand Up @@ -1787,13 +1819,15 @@ 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) {
FName meshName = createSafeName(loadResult.name, "");
UCesiumGltfPrimitiveComponent* pMesh =
NewObject<UCesiumGltfPrimitiveComponent>(pGltf, meshName);
NewObject<UCesiumGltfPrimitiveComponent>(pOutter, meshName);
pMesh->overlayTextureCoordinateIDToUVIndex =
loadResult.overlayTextureCoordinateIDToUVIndex;
pMesh->textureCoordinateMap = std::move(loadResult.textureCoordinateMap);
Expand Down Expand Up @@ -1991,8 +2025,10 @@ static void loadPrimitiveGameThreadPart(

// pMesh->bDrawMeshCollisionIfComplex = true;
// pMesh->bDrawMeshCollisionIfSimple = true;
pMesh->SetupAttachment(pGltf);
pMesh->SetupAttachment(pOutter);
pMesh->RegisterComponent();

return pMesh;
}

/*static*/ TUniquePtr<UCesiumGltfComponent::HalfConstructed>
Expand All @@ -2002,7 +2038,7 @@ UCesiumGltfComponent::CreateOffGameThread(
auto pResult = MakeUnique<HalfConstructedReal>();
loadModelAnyThreadPart(pResult->loadModelResult, Transform, Options);

return pResult;
return MoveTemp(pResult);
}

/*static*/ UCesiumGltfComponent* UCesiumGltfComponent::CreateOnGameThread(
Expand All @@ -2015,12 +2051,6 @@ UCesiumGltfComponent::CreateOffGameThread(
HalfConstructedReal* pReal =
static_cast<HalfConstructedReal*>(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<UCesiumGltfComponent>(pParentActor);
Gltf->SetUsingAbsoluteLocation(true);
Gltf->SetFlags(RF_Transient | RF_DuplicateTransient | RF_TextExportTransient);
Expand All @@ -2039,16 +2069,47 @@ UCesiumGltfComponent::CreateOffGameThread(
Gltf->CustomDepthParameters = CustomDepthParameters;

encodeMetadataGameThreadPart(Gltf->EncodedMetadata);
int32 nodeIndex = 0;
for (LoadNodeResult& node : pReal->loadModelResult.nodeResults) {
if (node.meshResult) {
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 (auto& meshResult : node.meshVariantsResults) {
std::vector<UCesiumGltfPrimitiveComponent*> mesh;
mesh.reserve(meshResult.second.primitiveResults.size());

for (LoadPrimitiveResult& primitive :
meshResult.second.primitiveResults) {
mesh.push_back(loadPrimitiveGameThreadPart(
Gltf,
pVariants,
primitive,
cesiumToUnrealTransform));
}

pVariants->AddMesh(meshResult.first, std::move(mesh));
}
} else if (node.meshResult) {
for (LoadPrimitiveResult& primitive : node.meshResult->primitiveResults) {
loadPrimitiveGameThreadPart(Gltf, primitive, cesiumToUnrealTransform);
loadPrimitiveGameThreadPart(
Gltf,
Gltf,
primitive,
cesiumToUnrealTransform);
}
}

++nodeIndex;
}

Gltf->SetVisibility(false, true);
Gltf->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Gltf->HideGltf();
return Gltf;
}

Expand Down Expand Up @@ -2080,17 +2141,37 @@ UCesiumGltfComponent::~UCesiumGltfComponent() {
UE_LOG(LogCesium, VeryVerbose, TEXT("~UCesiumGltfComponent"));
}

void UCesiumGltfComponent::UpdateTransformFromCesium(
const glm::dmat4& cesiumToUnrealTransform) {
for (USceneComponent* pSceneComponent : this->GetAttachChildren()) {
void UCesiumGltfComponent::ShowGltf() {
if (!this->GetVisibleFlag()) {
this->SetVisibleFlag(true);
this->OnVisibilityChanged();
}

for (USceneComponent* pComponent : this->GetAttachChildren()) {
UCesiumGltfPrimitiveComponent* pPrimitive =
Cast<UCesiumGltfPrimitiveComponent>(pSceneComponent);
if (pPrimitive) {
pPrimitive->UpdateTransformFromCesium(cesiumToUnrealTransform);
Cast<UCesiumGltfPrimitiveComponent>(pComponent);
UCesiumGltfMeshVariantsComponent* pVariant =
Cast<UCesiumGltfMeshVariantsComponent>(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);
}

namespace {

template <typename Func>
Expand Down
4 changes: 3 additions & 1 deletion Source/CesiumRuntime/Private/CesiumGltfComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class UCesiumGltfComponent : public USceneComponent {

CesiumEncodedMetadataUtility::EncodedMetadata EncodedMetadata;

void UpdateTransformFromCesium(const glm::dmat4& CesiumToUnrealTransform);
void ShowGltf();

void HideGltf();

void AttachRasterTile(
const Cesium3DTilesSelection::Tile& Tile,
Expand Down
Loading