You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Before: 3548 unity files Total CPU Time: 47343.578125 s Total time in Parallel executor: 494.60 seconds After: 3445 unity files Total CPU Time: 46044.671875 s Total time in Parallel executor: 468.51 seconds #jira #preflight 63336159b20e73a098b7f24f [CL 22218213 by bryan sefcik in ue5-main branch]
309 lines
7.4 KiB
C++
309 lines
7.4 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "AlignObjectsTool.h"
|
|
#include "InteractiveToolManager.h"
|
|
#include "ToolBuilderUtil.h"
|
|
#include "ToolSetupUtil.h"
|
|
#include "DynamicMesh/DynamicMesh3.h"
|
|
#include "MeshAdapterTransforms.h"
|
|
#include "DynamicMesh/MeshTransforms.h"
|
|
#include "BaseBehaviors/ClickDragBehavior.h"
|
|
#include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
|
|
#include "ToolTargetManager.h"
|
|
#include "ModelingToolTargetUtil.h"
|
|
|
|
#include "Components/PrimitiveComponent.h"
|
|
#include "CollisionQueryParams.h"
|
|
#include "Engine/World.h"
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(AlignObjectsTool)
|
|
|
|
using namespace UE::Geometry;
|
|
|
|
#define LOCTEXT_NAMESPACE "UAlignObjectsTool"
|
|
|
|
/*
|
|
* ToolBuilder
|
|
*/
|
|
|
|
const FToolTargetTypeRequirements& UAlignObjectsToolBuilder::GetTargetRequirements() const
|
|
{
|
|
static FToolTargetTypeRequirements TypeRequirements(
|
|
UPrimitiveComponentBackedTarget::StaticClass()
|
|
);
|
|
return TypeRequirements;
|
|
}
|
|
|
|
bool UAlignObjectsToolBuilder::CanBuildTool(const FToolBuilderState& SceneState) const
|
|
{
|
|
return SceneState.TargetManager->CountSelectedAndTargetable(SceneState, GetTargetRequirements()) >= 2;
|
|
}
|
|
|
|
UMultiSelectionMeshEditingTool* UAlignObjectsToolBuilder::CreateNewTool(const FToolBuilderState& SceneState) const
|
|
{
|
|
return NewObject<UAlignObjectsTool>(SceneState.ToolManager);
|
|
}
|
|
|
|
/*
|
|
* Tool
|
|
*/
|
|
|
|
UAlignObjectsTool::UAlignObjectsTool()
|
|
{
|
|
}
|
|
|
|
|
|
void UAlignObjectsTool::Setup()
|
|
{
|
|
UInteractiveTool::Setup();
|
|
|
|
UClickDragInputBehavior* ClickDragBehavior = NewObject<UClickDragInputBehavior>(this);
|
|
ClickDragBehavior->Initialize(this);
|
|
AddInputBehavior(ClickDragBehavior);
|
|
|
|
AlignProps = NewObject<UAlignObjectsToolProperties>();
|
|
AlignProps->RestoreProperties(this);
|
|
AddToolPropertySource(AlignProps);
|
|
|
|
Precompute();
|
|
|
|
SetToolDisplayName(LOCTEXT("ToolName", "Align"));
|
|
GetToolManager()->DisplayMessage(
|
|
LOCTEXT("OnStartTool", "This Tool aligns the Pivots or Bounding Boxes of the input Objects."),
|
|
EToolMessageLevel::UserNotification);
|
|
}
|
|
|
|
|
|
|
|
void UAlignObjectsTool::OnShutdown(EToolShutdownType ShutdownType)
|
|
{
|
|
AlignProps->SaveProperties(this);
|
|
|
|
// reset positions even on accept, because we need them to be updated below
|
|
for (const FAlignInfo& Align : ComponentInfo)
|
|
{
|
|
Align.Component->SetWorldTransform(Align.SavedTransform);
|
|
}
|
|
|
|
if (ShutdownType == EToolShutdownType::Accept)
|
|
{
|
|
GetToolManager()->BeginUndoTransaction(LOCTEXT("AlignObjectsTransactionName", "Align Objects"));
|
|
|
|
for (const FAlignInfo& Align : ComponentInfo)
|
|
{
|
|
Align.Component->Modify();
|
|
}
|
|
bAlignDirty = true;
|
|
UpdateAlignment();
|
|
|
|
GetToolManager()->EndUndoTransaction();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void UAlignObjectsTool::OnTick(float DeltaTime)
|
|
{
|
|
if (bAlignDirty)
|
|
{
|
|
UpdateAlignment();
|
|
bAlignDirty = false;
|
|
}
|
|
}
|
|
|
|
void UAlignObjectsTool::Render(IToolsContextRenderAPI* RenderAPI)
|
|
{
|
|
}
|
|
|
|
void UAlignObjectsTool::OnPropertyModified(UObject* PropertySet, FProperty* Property)
|
|
{
|
|
bAlignDirty = true;
|
|
}
|
|
|
|
|
|
void UAlignObjectsTool::RegisterActions(FInteractiveToolActionSet& ActionSet)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
void UAlignObjectsTool::Precompute()
|
|
{
|
|
PivotBounds = FAxisAlignedBox3d::Empty();
|
|
CombinedBounds = FAxisAlignedBox3d::Empty();
|
|
AveragePivot = FVector3d::Zero();
|
|
|
|
for (TObjectPtr<UToolTarget>& Target : Targets)
|
|
{
|
|
FAlignInfo AlignInfo;
|
|
AlignInfo.Component = UE::ToolTarget::GetTargetComponent(Target);
|
|
AlignInfo.SavedTransform = (FTransform) UE::ToolTarget::GetLocalToWorldTransform(Target);
|
|
AlignInfo.WorldTransform = UE::ToolTarget::GetLocalToWorldTransform(Target);
|
|
AlignInfo.WorldBounds = FAxisAlignedBox3d(AlignInfo.Component->Bounds.GetBox());
|
|
AlignInfo.WorldPivot = AlignInfo.WorldTransform.TransformPosition(FVector3d::Zero());
|
|
ComponentInfo.Add(AlignInfo);
|
|
|
|
CombinedBounds.Contain(AlignInfo.WorldBounds);
|
|
PivotBounds.Contain(AlignInfo.WorldPivot);
|
|
AveragePivot += AlignInfo.WorldPivot;
|
|
}
|
|
|
|
AveragePivot /= (double)ComponentInfo.Num();
|
|
|
|
bAlignDirty = true;
|
|
}
|
|
|
|
|
|
static FVector3d GetBoxPoint(const FAxisAlignedBox3d& Box, EAlignObjectsBoxPoint BoxPoint)
|
|
{
|
|
FVector3d Point = Box.Center();
|
|
switch(BoxPoint)
|
|
{
|
|
default:
|
|
case EAlignObjectsBoxPoint::Center:
|
|
break;
|
|
|
|
case EAlignObjectsBoxPoint::Top:
|
|
Point.Z = Box.Max.Z; break;
|
|
|
|
case EAlignObjectsBoxPoint::Bottom:
|
|
Point.Z = Box.Min.Z; break;
|
|
|
|
case EAlignObjectsBoxPoint::Left:
|
|
Point.Y = Box.Min.Y; break;
|
|
|
|
case EAlignObjectsBoxPoint::Right:
|
|
Point.Y = Box.Max.Y; break;
|
|
|
|
case EAlignObjectsBoxPoint::Front:
|
|
Point.X = Box.Min.X; break;
|
|
|
|
case EAlignObjectsBoxPoint::Back:
|
|
Point.X = Box.Max.X; break;
|
|
|
|
case EAlignObjectsBoxPoint::Min:
|
|
Point = Box.Min; break;
|
|
|
|
case EAlignObjectsBoxPoint::Max:
|
|
Point = Box.Max; break;
|
|
}
|
|
|
|
return Point;
|
|
}
|
|
|
|
|
|
void UAlignObjectsTool::UpdateAlignment()
|
|
{
|
|
if (AlignProps->AlignType == EAlignObjectsAlignTypes::Pivots)
|
|
{
|
|
UpdateAlignment_Pivots();
|
|
}
|
|
else if (AlignProps->AlignType == EAlignObjectsAlignTypes::BoundingBoxes)
|
|
{
|
|
UpdateAlignment_BoundingBoxes();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void UAlignObjectsTool::UpdateAlignment_Pivots()
|
|
{
|
|
FVector3d TargetPoint;
|
|
if (AlignProps->AlignTo == EAlignObjectsAlignToOptions::FirstSelected)
|
|
{
|
|
TargetPoint = ComponentInfo[0].WorldPivot;
|
|
}
|
|
else if (AlignProps->AlignTo == EAlignObjectsAlignToOptions::LastSelected)
|
|
{
|
|
TargetPoint = ComponentInfo[ComponentInfo.Num()-1].WorldPivot;
|
|
}
|
|
else
|
|
{
|
|
TargetPoint = GetBoxPoint(PivotBounds, AlignProps->BoxPosition);
|
|
}
|
|
|
|
for (const FAlignInfo& AlignObj : ComponentInfo)
|
|
{
|
|
FVector3d SourcePoint = AlignObj.WorldPivot;
|
|
|
|
FVector3d UseTarget(
|
|
(AlignProps->bAlignX) ? TargetPoint.X : SourcePoint.X,
|
|
(AlignProps->bAlignY) ? TargetPoint.Y : SourcePoint.Y,
|
|
(AlignProps->bAlignZ) ? TargetPoint.Z : SourcePoint.Z);
|
|
|
|
FVector3d Translation = UseTarget - SourcePoint;
|
|
FTransform3d NewTransform = AlignObj.WorldTransform;
|
|
NewTransform.SetTranslation(NewTransform.GetTranslation() + Translation);
|
|
AlignObj.Component->SetWorldTransform((FTransform)NewTransform);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UAlignObjectsTool::UpdateAlignment_BoundingBoxes()
|
|
{
|
|
FVector3d TargetPoint;
|
|
if (AlignProps->AlignTo == EAlignObjectsAlignToOptions::FirstSelected)
|
|
{
|
|
TargetPoint = GetBoxPoint(ComponentInfo[0].WorldBounds, AlignProps->BoxPosition);
|
|
}
|
|
else if (AlignProps->AlignTo == EAlignObjectsAlignToOptions::LastSelected)
|
|
{
|
|
TargetPoint = GetBoxPoint(ComponentInfo[ComponentInfo.Num()-1].WorldBounds, AlignProps->BoxPosition);
|
|
}
|
|
else
|
|
{
|
|
TargetPoint = GetBoxPoint(CombinedBounds, AlignProps->BoxPosition);
|
|
}
|
|
|
|
for (const FAlignInfo& AlignObj : ComponentInfo)
|
|
{
|
|
FVector3d SourcePoint = GetBoxPoint(AlignObj.WorldBounds, AlignProps->BoxPosition);
|
|
|
|
FVector3d UseTarget(
|
|
(AlignProps->bAlignX) ? TargetPoint.X : SourcePoint.X,
|
|
(AlignProps->bAlignY) ? TargetPoint.Y : SourcePoint.Y,
|
|
(AlignProps->bAlignZ) ? TargetPoint.Z : SourcePoint.Z);
|
|
|
|
FVector3d Translation = UseTarget - SourcePoint;
|
|
FTransform3d NewTransform = AlignObj.WorldTransform;
|
|
NewTransform.SetTranslation(NewTransform.GetTranslation() + Translation);
|
|
AlignObj.Component->SetWorldTransform((FTransform)NewTransform);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// does not make sense that CanBeginClickDragSequence() returns a RayHit? Needs to be an out-argument...
|
|
FInputRayHit UAlignObjectsTool::CanBeginClickDragSequence(const FInputDeviceRay& PressPos)
|
|
{
|
|
return FInputRayHit();
|
|
}
|
|
|
|
void UAlignObjectsTool::OnClickPress(const FInputDeviceRay& PressPos)
|
|
{
|
|
}
|
|
|
|
|
|
void UAlignObjectsTool::OnClickDrag(const FInputDeviceRay& DragPos)
|
|
{
|
|
}
|
|
|
|
|
|
void UAlignObjectsTool::OnClickRelease(const FInputDeviceRay& ReleasePos)
|
|
{
|
|
}
|
|
|
|
void UAlignObjectsTool::OnTerminateDragSequence()
|
|
{
|
|
}
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|
|
|