Skip to content

Commit

Permalink
高さ合わせ (#216)
Browse files Browse the repository at this point in the history
* LOD4 Import 用 library update

* temp update (build error)

* temp update (crash)

* temp update (軸変換未対応)

* Lib update (座標変換)

* 動作(LOD3 Road以外)

* const value fix

* lib update (mac build)

* lib update (mac crash fixed)

---------

Co-authored-by: COREI5\taka <seventhdim@gmail.com>
  • Loading branch information
sevendev and seventhX authored Jul 12, 2024
1 parent 60a8cba commit 79566ca
Show file tree
Hide file tree
Showing 37 changed files with 1,312 additions and 248 deletions.
4 changes: 2 additions & 2 deletions Content/EUW/ModelAdjustmentTab.uasset
Git LFS file not shown
4 changes: 2 additions & 2 deletions Content/EUW/ModelLandscapeTab.uasset
Git LFS file not shown
89 changes: 69 additions & 20 deletions Source/PLATEAURuntime/Private/PLATEAUInstancedCityModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <Reconstruct/PLATEAUModelClassificationByAttribute.h>
#include <Reconstruct/PLATEAUModelLandscape.h>
#include <Reconstruct/PLATEAUMeshLoaderForLandscape.h>
#include <Reconstruct/PLATEAUModelAlignLand.h>
#include "Tasks/Pipe.h"

using namespace UE::Tasks;
Expand Down Expand Up @@ -108,6 +109,15 @@ int APLATEAUInstancedCityModel::ParseLodComponent(const USceneComponent* const I
return Lod;
}

void APLATEAUInstancedCityModel::DestroyOrHideComponents(TArray<UPLATEAUCityObjectGroup*> Components, bool bDestroy) {
for (auto Comp : Components) {
if (bDestroy)
Comp->DestroyComponent();
else
Comp->SetVisibility(false);
}
}

// Sets default values
APLATEAUInstancedCityModel::APLATEAUInstancedCityModel() {
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
Expand Down Expand Up @@ -565,12 +575,7 @@ UE::Tasks::TTask<TArray<USceneComponent*>> APLATEAUInstancedCityModel::Reconstru
std::shared_ptr<plateau::polygonMesh::Model> converted = ModelReconstruct.ConvertModelForReconstruct(TargetCityObjects);
FFunctionGraphTask::CreateAndDispatchWhenReady([&]() {
//コンポーネント削除
for (auto comp : TargetCityObjects) {
if (bDestroyOriginal)
comp->DestroyComponent();
else
comp->SetVisibility(false);
}
DestroyOrHideComponents(TargetCityObjects, bDestroyOriginal);
}, TStatId(), NULL, ENamedThreads::GameThread)
->Wait();

Expand All @@ -580,12 +585,11 @@ UE::Tasks::TTask<TArray<USceneComponent*>> APLATEAUInstancedCityModel::Reconstru
return ConvertTask;
}


//Landscape
UE::Tasks::FTask APLATEAUInstancedCityModel::CreateLandscape(const TArray<USceneComponent*> TargetComponents, bool bDestroyOriginal, FPLATEAULandscapeParam Param) {
UE::Tasks::FTask APLATEAUInstancedCityModel::CreateLandscape(const TArray<USceneComponent*> TargetComponents, FPLATEAULandscapeParam Param, bool bDestroyOriginal) {

UE_LOG(LogTemp, Log, TEXT("CreateLandscape: %d %s"), TargetComponents.Num(), bDestroyOriginal ? TEXT("True") : TEXT("False"));
FTask CreateLandscapeTask = Launch(TEXT("CreateLandscapeTask"), [this, TargetComponents, bDestroyOriginal, Param] {
FTask CreateLandscapeTask = Launch(TEXT("CreateLandscapeTask"), [&, TargetComponents, Param, bDestroyOriginal] {

FPLATEAUModelLandscape Landscape(this);
const auto& TargetCityObjects = Landscape.GetUPLATEAUCityObjectGroupsFromSceneComponents(TargetComponents);
Expand All @@ -597,21 +601,66 @@ UE::Tasks::FTask APLATEAUInstancedCityModel::CreateLandscape(const TArray<UScene
ExtOptions.CoordinateSystem = ECoordinateSystem::ESU;
FPLATEAUMeshExporter MeshExporter;
std::shared_ptr<plateau::polygonMesh::Model> smodel = MeshExporter.CreateModelFromComponents(this, TargetCityObjects, ExtOptions);

Landscape.CreateLandscape(smodel,Param);

FFunctionGraphTask::CreateAndDispatchWhenReady([&,TargetCityObjects, bDestroyOriginal]() {
const auto Results = Landscape.CreateHeightMap(smodel, Param);

// 高さを地形に揃える
if (Param.AlignLand) {
auto AlignLandTask = AlignLand(Results, Param, bDestroyOriginal);
AddNested(AlignLandTask);
AlignLandTask.Wait();
const auto& AlignedComponents = AlignLandTask.GetResult();
FFunctionGraphTask::CreateAndDispatchWhenReady([&, AlignedComponents, bDestroyOriginal]() {
// Align コンポーネント削除
DestroyOrHideComponents(AlignedComponents, bDestroyOriginal);
}, TStatId(), NULL, ENamedThreads::GameThread)->Wait();
}

//コンポーネント削除
if (bDestroyOriginal) {
for (auto comp : TargetCityObjects) {
comp->DestroyComponent();
}
//TODO: // LOD3道路の場合、HeightMap書き換え

for (const auto Result : Results) {
//Landscape生成
if (Param.CreateLandscape) {
TArray<uint16> HeightData(Result.Data->data(), Result.Data->size());
//LandScape
FFunctionGraphTask::CreateAndDispatchWhenReady(
[&, HeightData, Result, Param] {
Landscape.CreateLandScape(GetWorld(), Param.NumSubsections, Param.SubsectionSizeQuads,
Param.ComponentCountX, Param.ComponentCountY,
Param.TextureWidth, Param.TextureHeight,
Result.Min, Result.Max, Result.MinUV, Result.MaxUV, Result.TexturePath, HeightData, Result.NodeName);
}, TStatId(), nullptr, ENamedThreads::GameThread)->Wait();
}
}

FFunctionGraphTask::CreateAndDispatchWhenReady([&, TargetCityObjects, bDestroyOriginal, Results]() {

// Landscape コンポーネント削除
if (Param.CreateLandscape)
DestroyOrHideComponents(TargetCityObjects, bDestroyOriginal);

//終了イベント通知
OnLandscapeCreationFinished.Broadcast();
}, TStatId(), NULL, ENamedThreads::GameThread);
});
EPLATEAULandscapeCreationResult Res = Results.Num() > 0 ? EPLATEAULandscapeCreationResult::Success : EPLATEAULandscapeCreationResult::Fail;
OnLandscapeCreationFinished.Broadcast(Res);
}, TStatId(), NULL, ENamedThreads::GameThread)->Wait();

});
return CreateLandscapeTask;
}

UE::Tasks::TTask<TArray<UPLATEAUCityObjectGroup*>> APLATEAUInstancedCityModel::AlignLand(const TArray<HeightmapCreationResult> Results, FPLATEAULandscapeParam Param, bool bDestroyOriginal) {

UE::Tasks::TTask<TArray<UPLATEAUCityObjectGroup*>> AlignLandTask = Launch(TEXT("AlignLandTask"), [&, this, Results, Param, bDestroyOriginal] {
FPLATEAUModelAlignLand AlignLand(this);
TArray<plateau::heightMapAligner::HeightMapFrame> Frames;
for (const auto Result : Results) {
Frames.Add(AlignLand.CreateAlignData(Result.Data, Result.Min, Result.Max, Result.NodeName, Param));
}

const auto TargetCityObjects = AlignLand.SetAlignData(Frames, Param);
return TargetCityObjects;

});
return AlignLandTask;
}

8 changes: 4 additions & 4 deletions Source/PLATEAURuntime/Private/PLATEAUMeshLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ namespace {
const auto InUV1 = InMesh.getUV1()[InIndices[InIndexIndex]];
const auto UV1 = FVector2f(InUV1.x, 1.0f - InUV1.y);
VertexInstanceUVs.Set(NewVertexInstanceID, 0, UV1);

const auto InUV4 = InMesh.getUV4()[InIndices[InIndexIndex]];
const auto UV4 = FVector2f(InUV4.x, InUV4.y);
VertexInstanceUVs.Set(NewVertexInstanceID, 3, UV4);
Expand Down Expand Up @@ -415,7 +415,7 @@ UStaticMeshComponent* FPLATEAUMeshLoader::CreateStaticMeshComponent(AActor& Acto
UE_LOG(LogTemp, Error, TEXT("SubMesh/PolygonGroups size wrong => %s %s SubMesh: %d PolygonGroups: %d "), *ParentComponent.GetName(), *NodeName, SubMeshMaterialSets.Num(), MeshDescription->PolygonGroups().Num());

const auto ComponentSetupTask = FFunctionGraphTask::CreateAndDispatchWhenReady(
[&SubMeshMaterialSets, this, &Component, &StaticMesh, &MeshDescription, &Actor, &ParentComponent, &ComponentRef, &LoadInputData] {
[&SubMeshMaterialSets, this, &Component, &StaticMesh, &MeshDescription, &Actor, &ParentComponent, &ComponentRef, &LoadInputData, NodeName] {
for (const auto& SubMeshValue : SubMeshMaterialSets) {
UMaterialInstanceDynamic** SharedMatPtr = CachedMaterials.Find(SubMeshValue);
if (SharedMatPtr == nullptr) {
Expand All @@ -440,7 +440,7 @@ UStaticMeshComponent* FPLATEAUMeshLoader::CreateStaticMeshComponent(AActor& Acto
}
}

DynMaterial = GetMaterialForSubMesh(SubMeshValue, Component, LoadInputData, Texture);
DynMaterial = GetMaterialForSubMesh(SubMeshValue, Component, LoadInputData, Texture, NodeName);

//Textureが存在する場合
if (Texture != nullptr)
Expand Down Expand Up @@ -501,7 +501,7 @@ UStaticMeshComponent* FPLATEAUMeshLoader::GetStaticMeshComponentForCondition(AAc
return NewObject<UPLATEAUStaticMeshComponent>(&Actor, NAME_None);
}

UMaterialInstanceDynamic* FPLATEAUMeshLoader::GetMaterialForSubMesh(const FSubMeshMaterialSet& SubMeshValue, UStaticMeshComponent* Component, const FLoadInputData& LoadInputData, UTexture2D* Texture) {
UMaterialInstanceDynamic* FPLATEAUMeshLoader::GetMaterialForSubMesh(const FSubMeshMaterialSet& SubMeshValue, UStaticMeshComponent* Component, const FLoadInputData& LoadInputData, UTexture2D* Texture, FString NodeName) {

UMaterialInstanceDynamic* DynMaterial = nullptr;
if (SubMeshValue.hasMaterial) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2023 Ministry of Land, Infrastructure and Transport


#include "Reconstruct/PLATEAUMeshLoaderCloneComponent.h"
#include "PLATEAUCityModelLoader.h"
#include "PLATEAUCityObjectGroup.h"
#include "PLATEAUInstancedCityModel.h"

FPLATEAUMeshLoaderCloneComponent::FPLATEAUMeshLoaderCloneComponent() {}

FPLATEAUMeshLoaderCloneComponent::FPLATEAUMeshLoaderCloneComponent(const bool InbAutomationTest){
bAutomationTest = InbAutomationTest;
}

TMap<FString, UPLATEAUCityObjectGroup*> FPLATEAUMeshLoaderCloneComponent::CreateComponentsMap(const TArray<UPLATEAUCityObjectGroup*> TargetCityObjects) {
TMap<FString, UPLATEAUCityObjectGroup*> Map;
for (auto Comp : TargetCityObjects) {
Map.Add(APLATEAUInstancedCityModel::GetOriginalComponentName(Comp), Comp);
}
return Map;
}

UPLATEAUCityObjectGroup* FPLATEAUMeshLoaderCloneComponent::GetOriginalComponent(FString Name) {
auto Ptr = ComponentsMap.Find(Name);
if (Ptr) {
const auto& OriginalComponent = *Ptr;
return OriginalComponent;
}
return nullptr;
}

void FPLATEAUMeshLoaderCloneComponent::ReloadComponentFromNode(
const plateau::polygonMesh::Node& InNode,
TMap<FString, UPLATEAUCityObjectGroup*> Components,
AActor& InActor) {

ComponentsMap = Components;
FPLATEAUMeshLoaderForReconstruct::ReloadComponentFromNode(nullptr, InNode, plateau::polygonMesh::MeshGranularity::PerPrimaryFeatureObject, TMap<FString, FPLATEAUCityObject>(), InActor);
}

UStaticMeshComponent* FPLATEAUMeshLoaderCloneComponent::GetStaticMeshComponentForCondition(AActor& Actor, EName Name, const std::string& InNodeName,
const plateau::polygonMesh::Mesh& InMesh, const FLoadInputData& LoadInputData,
const std::shared_ptr <const citygml::CityModel> CityModel) {

const FString NodeName = UTF8_TO_TCHAR(InNodeName.c_str());
const auto& PLATEAUCityObjectGroup = NewObject<UPLATEAUCityObjectGroup>(&Actor, NAME_None);

// Originalコンポーネントの属性をそのまま利用
const auto& OriginalComponent = GetOriginalComponent(NodeName);
if (OriginalComponent) {
PLATEAUCityObjectGroup->SerializedCityObjects = OriginalComponent->SerializedCityObjects;
PLATEAUCityObjectGroup->OutsideChildren = OriginalComponent->OutsideChildren;
PLATEAUCityObjectGroup->OutsideParent = OriginalComponent->OutsideParent;
PLATEAUCityObjectGroup->MeshGranularityIntValue = OriginalComponent->MeshGranularityIntValue;
}
return PLATEAUCityObjectGroup;
}

UMaterialInstanceDynamic* FPLATEAUMeshLoaderCloneComponent::GetMaterialForSubMesh(const FSubMeshMaterialSet& SubMeshValue, UStaticMeshComponent* Component, const FLoadInputData& LoadInputData, UTexture2D* Texture, FString NodeName) {

// Originalコンポーネントのマテリアルをそのまま利用
const auto& OriginalComponent = GetOriginalComponent(NodeName);
if (OriginalComponent)
return (UMaterialInstanceDynamic*)OriginalComponent->GetMaterial(0);

return FPLATEAUMeshLoader::GetMaterialForSubMesh(SubMeshValue, Component, LoadInputData, Texture, NodeName);
}

/**
* @brief Meshとコンポーネントが存在する場合、Originalコンポーネントと同一階層にCloneを配置します。それ以外は処理しません。
* ParentComponent, MeshGranularityパラメータは無視してコンポーネントの値を利用
*/
USceneComponent* FPLATEAUMeshLoaderCloneComponent::ReloadNode(USceneComponent* ParentComponent,
const plateau::polygonMesh::Node& Node,
plateau::polygonMesh::MeshGranularity Granularity,
AActor& Actor) {

if (Node.getMesh() != nullptr && Node.getMesh()->getVertices().size() > 0) {

const FString CompName = FString(UTF8_TO_TCHAR(Node.getName().c_str()));
const auto& OriginalComponent = GetOriginalComponent(CompName);

if (OriginalComponent) {

const auto& OriginalParentComponent = OriginalComponent->GetAttachParent();
const auto& OriginalGranularity = StaticCast<plateau::polygonMesh::MeshGranularity>(OriginalComponent->MeshGranularityIntValue);

plateau::polygonMesh::MeshExtractOptions MeshExtractOptions{};
MeshExtractOptions.mesh_granularity = OriginalGranularity;
FLoadInputData LoadInputData
{
MeshExtractOptions,
std::vector<plateau::geometry::Extent>{},
FString(),
false,
nullptr
};
return CreateStaticMeshComponent(Actor, *OriginalParentComponent, *Node.getMesh(), LoadInputData, nullptr,
Node.getName());
}
}
return nullptr;
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ FPLATEAUMeshLoaderForClassification::FPLATEAUMeshLoaderForClassification(const T
bAutomationTest = InbAutomationTest;
}

UMaterialInstanceDynamic* FPLATEAUMeshLoaderForClassification::GetMaterialForSubMesh(const FSubMeshMaterialSet& SubMeshValue, UStaticMeshComponent* Component, const FLoadInputData& LoadInputData, UTexture2D* Texture) {
UMaterialInstanceDynamic* FPLATEAUMeshLoaderForClassification::GetMaterialForSubMesh(const FSubMeshMaterialSet& SubMeshValue, UStaticMeshComponent* Component, const FLoadInputData& LoadInputData, UTexture2D* Texture, FString NodeName) {
if (SubMeshValue.GameMaterialID > -1 && !ClassificationMaterials.IsEmpty() && ClassificationMaterials.Contains(SubMeshValue.GameMaterialID)) {
const auto& MatPtr = ClassificationMaterials.Find(SubMeshValue.GameMaterialID);
if (MatPtr != nullptr) {
Expand All @@ -23,7 +23,7 @@ UMaterialInstanceDynamic* FPLATEAUMeshLoaderForClassification::GetMaterialForSub
return UMaterialInstanceDynamic::Create(Mat, Component);
}
}
return FPLATEAUMeshLoader::GetMaterialForSubMesh(SubMeshValue, Component, LoadInputData, Texture);
return FPLATEAUMeshLoader::GetMaterialForSubMesh(SubMeshValue, Component, LoadInputData, Texture, NodeName);
}


Loading

0 comments on commit 79566ca

Please sign in to comment.