You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- Add UE::ToolTarget::CommitMaterialSetUpdate() and ::CommitDynamicMeshUpdate(). ::GetDynamicMeshCopy() can now return tangents if requested. - Add IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). Default implementation does nothing, UStaticMeshComponentToolTarget implementation initializes auto-generated MeshDescription attributes. Used in ::GetDynamicMeshCopy() to get tangents (but requires a MeshDescription copy). - Clean up handling of Tangents in Simple/OctreeDynamicMeshComponent. Add local MakeTangentsFunc() to generate the Tangents lambda, handle different cases and no-tangents fallbacks consistently. - UDynamicMesh: add optional info arguments to EditMesh() and ChangeInfo struct. Add support for deferring change events from Edit funcs. - Remove UBaseDynamicMeshComponent::InitializeMesh(), ::Bake() APIs, and add ::SetMesh(). Implement in Simple/Octree implementations, update all Tools that used those APIs. - Add USimpleDynamicMeshComponent::ProcessMesh(), EditMesh(). These are now the preferred ways to read/write mesh. - Update USimpleDynamicMeshComponent tangents handling. Externally-computed tangents are now taken directly from the FDynamicMesh3 attribute set. Autogenerated tangents are still computed and stored in an internal FMeshTangentsf, but this is no longer exposed for external updates. - Remove UPreviewMesh pass-through functions for Tangents access, InitializeMesh() and Bake(). Add ProcessMesh() - Update all affected Tools. In most cases these Tools have also been converted to use ModelingToolTargetUtil functions, instead of direct ToolTarget interface casting. #rb none #rnx #jira none #preflight 60c3e71d3e1b3c00015668af [CL 16650666 by Ryan Schmidt in ue5-main branch]
279 lines
8.1 KiB
C++
279 lines
8.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "ModelingToolTargetUtil.h"
|
|
|
|
#include "ToolTargets/ToolTarget.h"
|
|
#include "TargetInterfaces/MaterialProvider.h"
|
|
#include "TargetInterfaces/MeshDescriptionCommitter.h"
|
|
#include "TargetInterfaces/MeshDescriptionProvider.h"
|
|
#include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
|
|
|
|
#include "ModelingObjectsCreationAPI.h"
|
|
|
|
#include "Components/PrimitiveComponent.h"
|
|
#include "Components/StaticMeshComponent.h"
|
|
#include "GameFramework/Volume.h"
|
|
#include "SimpleDynamicMeshComponent.h"
|
|
|
|
#include "MeshConversionOptions.h"
|
|
#include "MeshDescriptionToDynamicMesh.h"
|
|
#include "DynamicMeshToMeshDescription.h"
|
|
|
|
using namespace UE::Geometry;
|
|
|
|
AActor* UE::ToolTarget::GetTargetActor(UToolTarget* Target)
|
|
{
|
|
IPrimitiveComponentBackedTarget* TargetComponent = Cast<IPrimitiveComponentBackedTarget>(Target);
|
|
if (TargetComponent)
|
|
{
|
|
return TargetComponent->GetOwnerActor();
|
|
}
|
|
ensure(false);
|
|
return nullptr;
|
|
}
|
|
|
|
UPrimitiveComponent* UE::ToolTarget::GetTargetComponent(UToolTarget* Target)
|
|
{
|
|
IPrimitiveComponentBackedTarget* TargetComponent = Cast<IPrimitiveComponentBackedTarget>(Target);
|
|
if (TargetComponent)
|
|
{
|
|
return TargetComponent->GetOwnerComponent();
|
|
}
|
|
ensure(false);
|
|
return nullptr;
|
|
}
|
|
|
|
bool UE::ToolTarget::HideSourceObject(UToolTarget* Target)
|
|
{
|
|
IPrimitiveComponentBackedTarget* TargetComponent = Cast<IPrimitiveComponentBackedTarget>(Target);
|
|
if (TargetComponent)
|
|
{
|
|
TargetComponent->SetOwnerVisibility(false);
|
|
return true;
|
|
}
|
|
ensure(false);
|
|
return false;
|
|
}
|
|
|
|
bool UE::ToolTarget::ShowSourceObject(UToolTarget* Target)
|
|
{
|
|
IPrimitiveComponentBackedTarget* TargetComponent = Cast<IPrimitiveComponentBackedTarget>(Target);
|
|
if (TargetComponent)
|
|
{
|
|
TargetComponent->SetOwnerVisibility(true);
|
|
return true;
|
|
}
|
|
ensure(false);
|
|
return false;
|
|
}
|
|
|
|
|
|
FTransform3d UE::ToolTarget::GetLocalToWorldTransform(UToolTarget* Target)
|
|
{
|
|
IPrimitiveComponentBackedTarget* TargetComponent = Cast<IPrimitiveComponentBackedTarget>(Target);
|
|
if (TargetComponent)
|
|
{
|
|
return (FTransform3d)TargetComponent->GetWorldTransform();
|
|
}
|
|
ensure(false);
|
|
return FTransform3d();
|
|
}
|
|
|
|
FComponentMaterialSet UE::ToolTarget::GetMaterialSet(UToolTarget* Target, bool bPreferAssetMaterials)
|
|
{
|
|
FComponentMaterialSet MaterialSet;
|
|
IMaterialProvider* MaterialProvider = Cast<IMaterialProvider>(Target);
|
|
if (ensure(MaterialProvider))
|
|
{
|
|
MaterialProvider->GetMaterialSet(MaterialSet, bPreferAssetMaterials);
|
|
}
|
|
return MaterialSet;
|
|
}
|
|
|
|
|
|
bool UE::ToolTarget::CommitMaterialSetUpdate(
|
|
UToolTarget* Target,
|
|
const FComponentMaterialSet& UpdatedMaterials,
|
|
bool bApplyToAsset)
|
|
{
|
|
IMaterialProvider* MaterialProvider = Cast<IMaterialProvider>(Target);
|
|
if (MaterialProvider)
|
|
{
|
|
return MaterialProvider->CommitMaterialSetUpdate(UpdatedMaterials, bApplyToAsset);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
const FMeshDescription* UE::ToolTarget::GetMeshDescription(UToolTarget* Target)
|
|
{
|
|
static FMeshDescription EmptyMeshDescription;
|
|
|
|
IMeshDescriptionProvider* MeshDescriptionProvider = Cast<IMeshDescriptionProvider>(Target);
|
|
if (MeshDescriptionProvider)
|
|
{
|
|
return MeshDescriptionProvider->GetMeshDescription();
|
|
}
|
|
ensure(false);
|
|
return &EmptyMeshDescription;
|
|
}
|
|
|
|
|
|
FDynamicMesh3 UE::ToolTarget::GetDynamicMeshCopy(UToolTarget* Target, bool bWantMeshTangents)
|
|
{
|
|
IMeshDescriptionProvider* MeshDescriptionProvider = Cast<IMeshDescriptionProvider>(Target);
|
|
FDynamicMesh3 Mesh(EMeshComponents::FaceGroups);
|
|
Mesh.EnableAttributes();
|
|
if (MeshDescriptionProvider)
|
|
{
|
|
FMeshDescriptionToDynamicMesh Converter;
|
|
if (bWantMeshTangents)
|
|
{
|
|
// Currently to auto-calculate attributes we must make a copy, because they are written
|
|
// directly to the input mesh
|
|
FMeshDescription MeshDescriptionCopy( *MeshDescriptionProvider->GetMeshDescription() );
|
|
MeshDescriptionProvider->CalculateAutoGeneratedAttributes(MeshDescriptionCopy);
|
|
Converter.Convert(&MeshDescriptionCopy, Mesh, bWantMeshTangents);
|
|
}
|
|
else
|
|
{
|
|
Converter.Convert(MeshDescriptionProvider->GetMeshDescription(), Mesh, bWantMeshTangents);
|
|
}
|
|
|
|
return Mesh;
|
|
}
|
|
|
|
ensure(false);
|
|
return Mesh;
|
|
}
|
|
|
|
|
|
UE::ToolTarget::EDynamicMeshUpdateResult UE::ToolTarget::CommitMeshDescriptionUpdate(UToolTarget* Target, const FMeshDescription* UpdatedMesh, const FComponentMaterialSet* UpdatedMaterials)
|
|
{
|
|
IMeshDescriptionCommitter* MeshDescriptionCommitter = Cast<IMeshDescriptionCommitter>(Target);
|
|
if (!ensure(MeshDescriptionCommitter))
|
|
{
|
|
return EDynamicMeshUpdateResult::Failed;
|
|
}
|
|
|
|
if (UpdatedMaterials != nullptr)
|
|
{
|
|
CommitMaterialSetUpdate(Target, *UpdatedMaterials, true);
|
|
}
|
|
|
|
EDynamicMeshUpdateResult Result = EDynamicMeshUpdateResult::Failed;
|
|
MeshDescriptionCommitter->CommitMeshDescription([UpdatedMesh, &Result](const IMeshDescriptionCommitter::FCommitterParams& CommitParams)
|
|
{
|
|
*CommitParams.MeshDescriptionOut = *UpdatedMesh;
|
|
Result = EDynamicMeshUpdateResult::Ok;
|
|
});
|
|
return Result;
|
|
}
|
|
|
|
|
|
|
|
|
|
UE::ToolTarget::EDynamicMeshUpdateResult UE::ToolTarget::CommitDynamicMeshUpdate(
|
|
UToolTarget* Target, const FDynamicMesh3& UpdatedMesh,
|
|
bool bHaveModifiedTopology,
|
|
const FConversionToMeshDescriptionOptions& ConversionOptions,
|
|
const FComponentMaterialSet* UpdatedMaterials)
|
|
{
|
|
IMeshDescriptionCommitter* MeshDescriptionCommitter = Cast<IMeshDescriptionCommitter>(Target);
|
|
if (MeshDescriptionCommitter)
|
|
{
|
|
if (UpdatedMaterials != nullptr)
|
|
{
|
|
CommitMaterialSetUpdate(Target, *UpdatedMaterials, true);
|
|
}
|
|
|
|
EDynamicMeshUpdateResult Result = EDynamicMeshUpdateResult::Failed;
|
|
MeshDescriptionCommitter->CommitMeshDescription([&](const IMeshDescriptionCommitter::FCommitterParams& CommitParams)
|
|
{
|
|
FMeshDescription* MeshDescription = CommitParams.MeshDescriptionOut;
|
|
|
|
FDynamicMeshToMeshDescription Converter(ConversionOptions);
|
|
if (!bHaveModifiedTopology)
|
|
{
|
|
Converter.UpdateUsingConversionOptions(&UpdatedMesh, *MeshDescription);
|
|
Result = EDynamicMeshUpdateResult::Ok;
|
|
}
|
|
else
|
|
{
|
|
Converter.Convert(&UpdatedMesh, *MeshDescription);
|
|
Result = EDynamicMeshUpdateResult::Ok;
|
|
}
|
|
});
|
|
return Result;
|
|
}
|
|
|
|
ensure(false);
|
|
return EDynamicMeshUpdateResult::Failed;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UE::ToolTarget::EDynamicMeshUpdateResult UE::ToolTarget::CommitDynamicMeshUVUpdate(UToolTarget* Target, const UE::Geometry::FDynamicMesh3* UpdatedMesh)
|
|
{
|
|
IMeshDescriptionCommitter* MeshDescriptionCommitter = Cast<IMeshDescriptionCommitter>(Target);
|
|
if (!ensure(MeshDescriptionCommitter))
|
|
{
|
|
return EDynamicMeshUpdateResult::Failed;
|
|
}
|
|
|
|
EDynamicMeshUpdateResult Result = EDynamicMeshUpdateResult::Failed;
|
|
MeshDescriptionCommitter->CommitMeshDescription([UpdatedMesh, &Result](const IMeshDescriptionCommitter::FCommitterParams& CommitParams)
|
|
{
|
|
FMeshDescription* MeshDescription = CommitParams.MeshDescriptionOut;
|
|
|
|
bool bVerticesOnly = false;
|
|
bool bAttributesOnly = true;
|
|
if (FDynamicMeshToMeshDescription::HaveMatchingElementCounts(UpdatedMesh, MeshDescription, bVerticesOnly, bAttributesOnly))
|
|
{
|
|
FDynamicMeshToMeshDescription Converter;
|
|
Converter.UpdateAttributes(UpdatedMesh, *MeshDescription, false, false, true/*update uvs*/);
|
|
Result = EDynamicMeshUpdateResult::Ok;
|
|
}
|
|
else
|
|
{
|
|
// must have been duplicate tris in the mesh description; we can't count on 1-to-1 mapping of TriangleIDs. Just convert
|
|
FDynamicMeshToMeshDescription Converter;
|
|
Converter.Convert(UpdatedMesh, *MeshDescription);
|
|
Result = EDynamicMeshUpdateResult::Ok_ForcedFullUpdate;
|
|
}
|
|
});
|
|
return Result;
|
|
}
|
|
|
|
|
|
|
|
bool UE::ToolTarget::ConfigureCreateMeshObjectParams(UToolTarget* SourceTarget, FCreateMeshObjectParams& DerivedParamsOut)
|
|
{
|
|
IPrimitiveComponentBackedTarget* ComponentTarget = Cast<IPrimitiveComponentBackedTarget>(SourceTarget);
|
|
if (ComponentTarget)
|
|
{
|
|
if (Cast<UStaticMeshComponent>(ComponentTarget->GetOwnerComponent()) != nullptr)
|
|
{
|
|
DerivedParamsOut.TypeHint = ECreateObjectTypeHint::StaticMesh;
|
|
return true;
|
|
}
|
|
|
|
if (Cast<USimpleDynamicMeshComponent>(ComponentTarget->GetOwnerComponent()) != nullptr)
|
|
{
|
|
DerivedParamsOut.TypeHint = ECreateObjectTypeHint::DynamicMeshActor;
|
|
return true;
|
|
}
|
|
|
|
AVolume* VolumeActor = Cast<AVolume>(ComponentTarget->GetOwnerActor());
|
|
if (VolumeActor != nullptr)
|
|
{
|
|
DerivedParamsOut.TypeHint = ECreateObjectTypeHint::Volume;
|
|
DerivedParamsOut.TypeHintClass = VolumeActor->GetClass();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
} |