From bb66f7e357f055ee66628dfeb44b193db27d368a Mon Sep 17 00:00:00 2001 From: andrew davidson Date: Wed, 16 Mar 2022 03:30:04 -0400 Subject: [PATCH] Fix float math struct proxy customizations (FTransform, FMatrix, FQuat) #jira UE-145983 #rb zak.middleton #lockdown nick.whiting #preflight 6230faf5ac0173aa4123c050 #ROBOMERGE-OWNER: andrew.davidson #ROBOMERGE-AUTHOR: andrew.davidson #ROBOMERGE-SOURCE: CL 19396721 in //UE5/Release-5.0/... via CL 19398359 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v926-19321884) [CL 19403218 by andrew davidson in ue5-main branch] --- .../Private/DetailCustomizations.cpp | 18 +- .../Private/MathStructProxyCustomizations.cpp | 243 ++++++++++-------- .../MathStructProxyCustomizations.h | 76 +++--- 3 files changed, 181 insertions(+), 156 deletions(-) diff --git a/Engine/Source/Editor/DetailCustomizations/Private/DetailCustomizations.cpp b/Engine/Source/Editor/DetailCustomizations/Private/DetailCustomizations.cpp index 7884314c42dc..64e8dbdfb579 100644 --- a/Engine/Source/Editor/DetailCustomizations/Private/DetailCustomizations.cpp +++ b/Engine/Source/Editor/DetailCustomizations/Private/DetailCustomizations.cpp @@ -222,15 +222,15 @@ void FDetailCustomizationsModule::RegisterPropertyTypeCustomizations() REGISTER_UIMINMAX_CUSTOMIZATION(NAME_Rotator3d, &FRotatorStructCustomization::MakeInstance); RegisterCustomPropertyTypeLayout(NAME_LinearColor, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FColorStructCustomization::MakeInstance)); RegisterCustomPropertyTypeLayout(NAME_Color, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FColorStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Matrix, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Matrix44f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Matrix44d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Transform, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Transform3f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Transform3d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Quat, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Quat4f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); - RegisterCustomPropertyTypeLayout(NAME_Quat4d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Matrix, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Matrix44f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Matrix44d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FMatrixStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Transform, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Transform3f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Transform3d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FTransformStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Quat, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Quat4f, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); + RegisterCustomPropertyTypeLayout(NAME_Quat4d, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FQuatStructCustomization::MakeInstance)); RegisterCustomPropertyTypeLayout("SlateColor", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FSlateColorCustomization::MakeInstance)); RegisterCustomPropertyTypeLayout("ForceFeedbackAttenuationSettings", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FForceFeedbackAttenuationSettingsCustomization::MakeInstance)); RegisterCustomPropertyTypeLayout("SoundAttenuationSettings", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FSoundAttenuationSettingsCustomization::MakeInstance)); diff --git a/Engine/Source/Editor/DetailCustomizations/Private/MathStructProxyCustomizations.cpp b/Engine/Source/Editor/DetailCustomizations/Private/MathStructProxyCustomizations.cpp index cbf5195e1af1..0578318c746b 100644 --- a/Engine/Source/Editor/DetailCustomizations/Private/MathStructProxyCustomizations.cpp +++ b/Engine/Source/Editor/DetailCustomizations/Private/MathStructProxyCustomizations.cpp @@ -111,12 +111,14 @@ FText FMathStructProxyCustomization::OnGetValueToolTip(TWeakPtr return FText::GetEmpty(); } -TSharedRef FMatrixStructCustomization::MakeInstance() +template +TSharedRef FMatrixStructCustomization::MakeInstance() { - return MakeShareable( new FMatrixStructCustomization ); + return MakeShareable( new FMatrixStructCustomization ); } -void FMatrixStructCustomization::MakeHeaderRow(TSharedRef& StructPropertyHandle, FDetailWidgetRow& Row) +template +void FMatrixStructCustomization::MakeHeaderRow(TSharedRef& StructPropertyHandle, FDetailWidgetRow& Row) { Row .NameContent() @@ -131,13 +133,14 @@ void FMatrixStructCustomization::MakeHeaderRow(TSharedRef ]; } -void FMatrixStructCustomization::CustomizeLocation(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) +template +void FMatrixStructCustomization::CustomizeLocation(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) { TWeakPtr WeakHandlePtr = StructPropertyHandle; Row - .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Location, WeakHandlePtr))) - .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Location, WeakHandlePtr))) + .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Location, WeakHandlePtr))) + .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Location, WeakHandlePtr))) .NameContent() [ StructPropertyHandle->CreatePropertyNameWidget(LOCTEXT("LocationLabel", "Location")) @@ -150,29 +153,29 @@ void FMatrixStructCustomization::CustomizeLocation(TSharedRef(StructPropertyHandle, CachedTranslationX, LOCTEXT("TranslationX", "X"), false, SNumericEntryBox::RedLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedTranslationX, LOCTEXT("TranslationX", "X"), false, SNumericEntryBox::RedLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 3.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedTranslationY, LOCTEXT("TranslationY", "Y"), false, SNumericEntryBox::GreenLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedTranslationY, LOCTEXT("TranslationY", "Y"), false, SNumericEntryBox::GreenLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 0.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedTranslationZ, LOCTEXT("TranslationZ", "Z"), false, SNumericEntryBox::BlueLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedTranslationZ, LOCTEXT("TranslationZ", "Z"), false, SNumericEntryBox::BlueLabelBackgroundColor) ] ]; } - -void FMatrixStructCustomization::CustomizeRotation(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) +template +void FMatrixStructCustomization::CustomizeRotation(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) { TWeakPtr WeakHandlePtr = StructPropertyHandle; Row - .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Rotation, WeakHandlePtr))) - .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Rotation, WeakHandlePtr))) + .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Rotation, WeakHandlePtr))) + .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Rotation, WeakHandlePtr))) .NameContent() [ StructPropertyHandle->CreatePropertyNameWidget(LOCTEXT("RotationLabel", "Rotation")) @@ -185,29 +188,29 @@ void FMatrixStructCustomization::CustomizeRotation(TSharedRef(StructPropertyHandle, CachedRotationRoll, LOCTEXT("RotationRoll", "X"), true, SNumericEntryBox::RedLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedRotationRoll, LOCTEXT("RotationRoll", "X"), true, SNumericEntryBox::RedLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 3.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedRotationPitch, LOCTEXT("RotationPitch", "Y"), true, SNumericEntryBox::GreenLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedRotationPitch, LOCTEXT("RotationPitch", "Y"), true, SNumericEntryBox::GreenLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 0.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedRotationYaw, LOCTEXT("RotationYaw", "Z"), true, SNumericEntryBox::BlueLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedRotationYaw, LOCTEXT("RotationYaw", "Z"), true, SNumericEntryBox::BlueLabelBackgroundColor) ] ]; } - -void FMatrixStructCustomization::CustomizeScale(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) +template +void FMatrixStructCustomization::CustomizeScale(TSharedRef StructPropertyHandle, FDetailWidgetRow& Row) { TWeakPtr WeakHandlePtr = StructPropertyHandle; Row - .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Scale, WeakHandlePtr))) - .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Scale, WeakHandlePtr))) + .CopyAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnCopy, FTransformField::Scale, WeakHandlePtr))) + .PasteAction(FUIAction(FExecuteAction::CreateSP(this, &FMatrixStructCustomization::OnPaste, FTransformField::Scale, WeakHandlePtr))) .NameContent() [ StructPropertyHandle->CreatePropertyNameWidget(LOCTEXT("ScaleLabel", "Scale")) @@ -220,22 +223,23 @@ void FMatrixStructCustomization::CustomizeScale(TSharedRef(StructPropertyHandle, CachedScaleX, LOCTEXT("ScaleX", "X"), false, SNumericEntryBox::RedLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedScaleX, LOCTEXT("ScaleX", "X"), false, SNumericEntryBox::RedLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 3.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedScaleY, LOCTEXT("ScaleY", "Y"), false, SNumericEntryBox::GreenLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedScaleY, LOCTEXT("ScaleY", "Y"), false, SNumericEntryBox::GreenLabelBackgroundColor) ] + SHorizontalBox::Slot() .Padding(FMargin(0.0f, 2.0f, 0.0f, 2.0f)) [ - MakeNumericProxyWidget(StructPropertyHandle, CachedScaleZ, LOCTEXT("ScaleZ", "Z"), false, SNumericEntryBox::BlueLabelBackgroundColor) + MakeNumericProxyWidget, T>(StructPropertyHandle, CachedScaleZ, LOCTEXT("ScaleZ", "Z"), false, SNumericEntryBox::BlueLabelBackgroundColor) ] ]; } -void FMatrixStructCustomization::CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) +template +void FMatrixStructCustomization::CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { FMathStructProxyCustomization::CustomizeChildren(StructPropertyHandle, StructBuilder, StructCustomizationUtils); @@ -246,7 +250,8 @@ void FMatrixStructCustomization::CustomizeChildren(TSharedRef PropertyHandlePtr) +template +void FMatrixStructCustomization::OnCopy(FTransformField::Type Type, TWeakPtr PropertyHandlePtr) { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -262,21 +267,21 @@ void FMatrixStructCustomization::OnCopy(FTransformField::Type Type, TWeakPtrGet(); + UE::Math::TVector Location = CachedTranslation->Get(); CopyStr = FString::Printf(TEXT("(X=%f,Y=%f,Z=%f)"), Location.X, Location.Y, Location.Z); break; } case FTransformField::Rotation: { - FRotator Rotation = CachedRotation->Get(); + UE::Math::TRotator Rotation = CachedRotation->Get(); CopyStr = FString::Printf(TEXT("(Pitch=%f,Yaw=%f,Roll=%f)"), Rotation.Pitch, Rotation.Yaw, Rotation.Roll); break; } case FTransformField::Scale: { - FVector Scale = CachedScale->Get(); + UE::Math::TVector Scale = CachedScale->Get(); CopyStr = FString::Printf(TEXT("(X=%f,Y=%f,Z=%f)"), Scale.X, Scale.Y, Scale.Z); break; } @@ -288,7 +293,8 @@ void FMatrixStructCustomization::OnCopy(FTransformField::Type Type, TWeakPtr PropertyHandlePtr) +template +void FMatrixStructCustomization::OnPaste(FTransformField::Type Type, TWeakPtr PropertyHandlePtr) { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -304,7 +310,7 @@ void FMatrixStructCustomization::OnPaste(FTransformField::Type Type, TWeakPtr Location; if (Location.InitFromString(PastedText)) { FScopedTransaction Transaction(LOCTEXT("PasteLocation", "Paste Location")); @@ -318,7 +324,7 @@ void FMatrixStructCustomization::OnPaste(FTransformField::Type Type, TWeakPtr Rotation; PastedText.ReplaceInline(TEXT("Pitch="), TEXT("P=")); PastedText.ReplaceInline(TEXT("Yaw="), TEXT("Y=")); PastedText.ReplaceInline(TEXT("Roll="), TEXT("R=")); @@ -335,7 +341,7 @@ void FMatrixStructCustomization::OnPaste(FTransformField::Type Type, TWeakPtr Scale; if (Scale.InitFromString(PastedText)) { FScopedTransaction Transaction(LOCTEXT("PasteScale", "Paste Scale")); @@ -349,7 +355,8 @@ void FMatrixStructCustomization::OnPaste(FTransformField::Type Type, TWeakPtr PropertyHandlePtr ) const +template +bool FMatrixStructCustomization::CacheValues( TWeakPtr PropertyHandlePtr ) const { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -361,10 +368,10 @@ bool FMatrixStructCustomization::CacheValues( TWeakPtr Property TArray RawData; PropertyHandle->AccessRawData(RawData); - const FMatrix* FirstMatrixValue = nullptr; + const UE::Math::TMatrix* FirstMatrixValue = nullptr; for(void* RawDataPtr : RawData) { - FMatrix* MatrixValue = reinterpret_cast(RawDataPtr); + UE::Math::TMatrix* MatrixValue = reinterpret_cast*>(RawDataPtr); if (MatrixValue == nullptr) { return false; @@ -394,7 +401,8 @@ bool FMatrixStructCustomization::CacheValues( TWeakPtr Property return false; } -bool FMatrixStructCustomization::FlushValues( TWeakPtr PropertyHandlePtr ) const +template +bool FMatrixStructCustomization::FlushValues( TWeakPtr PropertyHandlePtr ) const { auto PropertyHandle = PropertyHandlePtr.Pin(); if (!PropertyHandle.IsValid()) @@ -417,31 +425,31 @@ bool FMatrixStructCustomization::FlushValues( TWeakPtr Property bool bNotifiedPreChange = false; for (int32 ValueIndex = 0; ValueIndex < RawData.Num(); ValueIndex++) { - FMatrix* MatrixValue = reinterpret_cast(RawData[ValueIndex]); + UE::Math::TMatrix* MatrixValue = reinterpret_cast*>(RawData[ValueIndex]); if (MatrixValue != NULL) { - const FMatrix PreviousValue = *MatrixValue; - const FRotator CurrentRotation = MatrixValue->Rotator(); - const FVector CurrentTranslation = MatrixValue->GetOrigin(); - const FVector CurrentScale = MatrixValue->GetScaleVector(); + const UE::Math::TMatrix PreviousValue = *MatrixValue; + const UE::Math::TRotator CurrentRotation = MatrixValue->Rotator(); + const UE::Math::TVector CurrentTranslation = MatrixValue->GetOrigin(); + const UE::Math::TVector CurrentScale = MatrixValue->GetScaleVector(); - FRotator Rotation( + UE::Math::TRotator Rotation( CachedRotationPitch->IsSet() ? CachedRotationPitch->Get() : CurrentRotation.Pitch, CachedRotationYaw->IsSet() ? CachedRotationYaw->Get() : CurrentRotation.Yaw, CachedRotationRoll->IsSet() ? CachedRotationRoll->Get() : CurrentRotation.Roll ); - FVector Translation( + UE::Math::TVector Translation( CachedTranslationX->IsSet() ? CachedTranslationX->Get() : CurrentTranslation.X, CachedTranslationY->IsSet() ? CachedTranslationY->Get() : CurrentTranslation.Y, CachedTranslationZ->IsSet() ? CachedTranslationZ->Get() : CurrentTranslation.Z ); - FVector Scale( + UE::Math::TVector Scale( CachedScaleX->IsSet() ? CachedScaleX->Get() : CurrentScale.X, CachedScaleY->IsSet() ? CachedScaleY->Get() : CurrentScale.Y, CachedScaleZ->IsSet() ? CachedScaleZ->Get() : CurrentScale.Z ); - const FMatrix NewValue = FScaleRotationTranslationMatrix(Scale, Rotation, Translation); + const UE::Math::TMatrix NewValue = UE::Math::TScaleRotationTranslationMatrix(Scale, Rotation, Translation); if (!bNotifiedPreChange && (!MatrixValue->Equals(NewValue, 0.0f) || (!bIsUsingSlider && bIsInteractiveChangeInProgress))) { @@ -461,14 +469,14 @@ bool FMatrixStructCustomization::FlushValues( TWeakPtr Property // Propagate default value changes after updating, for archetypes. As per usual, we only propagate the change if the instance matches the archetype's value. // Note: We cannot use the "normal" PropertyNode propagation logic here, because that is string-based and the decision to propagate relies on an exact value match. - // Here, we're dealing with conversions between FMatrix and FVector/FRotator values, so there is some precision loss that requires a tolerance when comparing values. + // Here, we're dealing with conversions between UE::Math::TMatrix and UE::Math::TVector/UE::Math::TRotator values, so there is some precision loss that requires a tolerance when comparing values. if (ValueIndex < OuterObjects.Num() && OuterObjects[ValueIndex]->IsTemplate()) { TArray ArchetypeInstances; OuterObjects[ValueIndex]->GetArchetypeInstances(ArchetypeInstances); for (UObject* ArchetypeInstance : ArchetypeInstances) { - FMatrix* CurrentValue = reinterpret_cast(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); + UE::Math::TMatrix* CurrentValue = reinterpret_cast*>(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); if (CurrentValue && CurrentValue->Equals(PreviousValue)) { *CurrentValue = NewValue; @@ -498,12 +506,14 @@ bool FMatrixStructCustomization::FlushValues( TWeakPtr Property return true; } -TSharedRef FTransformStructCustomization::MakeInstance() +template +TSharedRef FTransformStructCustomization::MakeInstance() { return MakeShareable( new FTransformStructCustomization ); } -bool FTransformStructCustomization::CacheValues( TWeakPtr PropertyHandlePtr ) const +template +bool FTransformStructCustomization::CacheValues( TWeakPtr PropertyHandlePtr ) const { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -515,10 +525,10 @@ bool FTransformStructCustomization::CacheValues( TWeakPtr Prope TArray RawData; PropertyHandle->AccessRawData(RawData); - const FTransform* FirstTransformValue = nullptr; + const UE::Math::TTransform* FirstTransformValue = nullptr; for(void* RawDataPtr : RawData) { - FTransform* TransformValue = reinterpret_cast(RawDataPtr); + UE::Math::TTransform* TransformValue = reinterpret_cast*>(RawDataPtr); if (TransformValue == nullptr) { return false; @@ -539,16 +549,17 @@ bool FTransformStructCustomization::CacheValues( TWeakPtr Prope if(FirstTransformValue) { - CachedTranslation->Set(FirstTransformValue->GetTranslation()); - CachedRotation->Set(FirstTransformValue->GetRotation().Rotator()); - CachedScale->Set(FirstTransformValue->GetScale3D()); + this->CachedTranslation->Set(FirstTransformValue->GetTranslation()); + this->CachedRotation->Set(FirstTransformValue->GetRotation().Rotator()); + this->CachedScale->Set(FirstTransformValue->GetScale3D()); return true; } return false; } -bool FTransformStructCustomization::FlushValues( TWeakPtr PropertyHandlePtr ) const +template +bool FTransformStructCustomization::FlushValues( TWeakPtr PropertyHandlePtr ) const { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -572,33 +583,33 @@ bool FTransformStructCustomization::FlushValues( TWeakPtr Prope bool bNotifiedPreChange = false; for (int32 ValueIndex = 0; ValueIndex < RawData.Num(); ValueIndex++) { - FTransform* TransformValue = reinterpret_cast(RawData[0]); + UE::Math::TTransform* TransformValue = reinterpret_cast*>(RawData[0]); if (TransformValue != NULL) { - const FTransform PreviousValue = *TransformValue; - const FRotator CurrentRotation = TransformValue->GetRotation().Rotator(); - const FVector CurrentTranslation = TransformValue->GetTranslation(); - const FVector CurrentScale = TransformValue->GetScale3D(); + const UE::Math::TTransform PreviousValue = *TransformValue; + const UE::Math::TRotator CurrentRotation = TransformValue->GetRotation().Rotator(); + const UE::Math::TVector CurrentTranslation = TransformValue->GetTranslation(); + const UE::Math::TVector CurrentScale = TransformValue->GetScale3D(); - FRotator Rotation( - CachedRotationPitch->IsSet() ? CachedRotationPitch->Get() : CurrentRotation.Pitch, - CachedRotationYaw->IsSet() ? CachedRotationYaw->Get() : CurrentRotation.Yaw, - CachedRotationRoll->IsSet() ? CachedRotationRoll->Get() : CurrentRotation.Roll + UE::Math::TRotator Rotation( + this->CachedRotationPitch->IsSet() ? this->CachedRotationPitch->Get() : CurrentRotation.Pitch, + this->CachedRotationYaw->IsSet() ? this->CachedRotationYaw->Get() : CurrentRotation.Yaw, + this->CachedRotationRoll->IsSet() ? this->CachedRotationRoll->Get() : CurrentRotation.Roll ); - FVector Translation( - CachedTranslationX->IsSet() ? CachedTranslationX->Get() : CurrentTranslation.X, - CachedTranslationY->IsSet() ? CachedTranslationY->Get() : CurrentTranslation.Y, - CachedTranslationZ->IsSet() ? CachedTranslationZ->Get() : CurrentTranslation.Z + UE::Math::TVector Translation( + this->CachedTranslationX->IsSet() ? this->CachedTranslationX->Get() : CurrentTranslation.X, + this->CachedTranslationY->IsSet() ? this->CachedTranslationY->Get() : CurrentTranslation.Y, + this->CachedTranslationZ->IsSet() ? this->CachedTranslationZ->Get() : CurrentTranslation.Z ); - FVector Scale( - CachedScaleX->IsSet() ? CachedScaleX->Get() : CurrentScale.X, - CachedScaleY->IsSet() ? CachedScaleY->Get() : CurrentScale.Y, - CachedScaleZ->IsSet() ? CachedScaleZ->Get() : CurrentScale.Z + UE::Math::TVector Scale( + this->CachedScaleX->IsSet() ? this->CachedScaleX->Get() : CurrentScale.X, + this->CachedScaleY->IsSet() ? this->CachedScaleY->Get() : CurrentScale.Y, + this->CachedScaleZ->IsSet() ? this->CachedScaleZ->Get() : CurrentScale.Z ); - const FTransform NewValue = FTransform(Rotation, Translation, Scale); + const UE::Math::TTransform NewValue = UE::Math::TTransform(Rotation, Translation, Scale); - if (!bNotifiedPreChange && (!TransformValue->Equals(NewValue, 0.0f) || (!bIsUsingSlider && bIsInteractiveChangeInProgress))) + if (!bNotifiedPreChange && (!TransformValue->Equals(NewValue, 0.0f) || (!this->bIsUsingSlider && bIsInteractiveChangeInProgress))) { if (!bIsInteractiveChangeInProgress) { @@ -608,7 +619,7 @@ bool FTransformStructCustomization::FlushValues( TWeakPtr Prope PropertyHandle->NotifyPreChange(); bNotifiedPreChange = true; - bIsInteractiveChangeInProgress = bIsUsingSlider; + bIsInteractiveChangeInProgress = this->bIsUsingSlider; } // Set the new value. @@ -616,14 +627,14 @@ bool FTransformStructCustomization::FlushValues( TWeakPtr Prope // Propagate default value changes after updating, for archetypes. As per usual, we only propagate the change if the instance matches the archetype's value. // Note: We cannot use the "normal" PropertyNode propagation logic here, because that is string-based and the decision to propagate relies on an exact value match. - // Here, we're dealing with conversions between FTransform and FVector/FRotator values, so there is some precision loss that requires a tolerance when comparing values. + // Here, we're dealing with conversions between UE::Math::TTransform and UE::Math::TVector/UE::Math::TRotator values, so there is some precision loss that requires a tolerance when comparing values. if (ValueIndex < OuterObjects.Num() && OuterObjects[ValueIndex]->IsTemplate()) { TArray ArchetypeInstances; OuterObjects[ValueIndex]->GetArchetypeInstances(ArchetypeInstances); for (UObject* ArchetypeInstance : ArchetypeInstances) { - FTransform* CurrentValue = reinterpret_cast(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); + UE::Math::TTransform* CurrentValue = reinterpret_cast*>(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); if (CurrentValue && CurrentValue->Equals(PreviousValue)) { *CurrentValue = NewValue; @@ -635,44 +646,45 @@ bool FTransformStructCustomization::FlushValues( TWeakPtr Prope if (bNotifiedPreChange) { - PropertyHandle->NotifyPostChange(bIsUsingSlider ? EPropertyChangeType::Interactive : EPropertyChangeType::ValueSet); + PropertyHandle->NotifyPostChange(this->bIsUsingSlider ? EPropertyChangeType::Interactive : EPropertyChangeType::ValueSet); - if (!bIsUsingSlider) + if (!this->bIsUsingSlider) { GEditor->EndTransaction(); bIsInteractiveChangeInProgress = false; } } - if (PropertyUtilities.IsValid() && !bIsInteractiveChangeInProgress) + if (this->PropertyUtilities.IsValid() && !bIsInteractiveChangeInProgress) { FPropertyChangedEvent ChangeEvent(PropertyHandle->GetProperty(), EPropertyChangeType::ValueSet, OuterObjects); - PropertyUtilities->NotifyFinishedChangingProperties(ChangeEvent); + this->PropertyUtilities->NotifyFinishedChangingProperties(ChangeEvent); } return true; } - -TSharedRef FQuatStructCustomization::MakeInstance() +template +TSharedRef FQuatStructCustomization::MakeInstance() { return MakeShareable(new FQuatStructCustomization); } -void FQuatStructCustomization::MakeHeaderRow(TSharedRef& InStructPropertyHandle, FDetailWidgetRow& Row) +template +void FQuatStructCustomization::MakeHeaderRow(TSharedRef& InStructPropertyHandle, FDetailWidgetRow& Row) { - CustomizeRotation(InStructPropertyHandle, Row); + this->CustomizeRotation(InStructPropertyHandle, Row); } - -void FQuatStructCustomization::CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) +template +void FQuatStructCustomization::CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { FMathStructProxyCustomization::CustomizeChildren(StructPropertyHandle, StructBuilder, StructCustomizationUtils); } - -bool FQuatStructCustomization::CacheValues(TWeakPtr PropertyHandlePtr) const +template +bool FQuatStructCustomization::CacheValues(TWeakPtr PropertyHandlePtr) const { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -686,10 +698,10 @@ bool FQuatStructCustomization::CacheValues(TWeakPtr PropertyHan if (RawData.Num() == 1) { - FQuat* QuatValue = reinterpret_cast(RawData[0]); + UE::Math::TQuat* QuatValue = reinterpret_cast*>(RawData[0]); if (QuatValue != NULL) { - CachedRotation->Set(QuatValue->Rotator()); + this->CachedRotation->Set(QuatValue->Rotator()); return true; } } @@ -697,7 +709,8 @@ bool FQuatStructCustomization::CacheValues(TWeakPtr PropertyHan return false; } -bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHandlePtr) const +template +bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHandlePtr) const { auto PropertyHandle = PropertyHandlePtr.Pin(); @@ -721,25 +734,25 @@ bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHan bool bNotifiedPreChange = false; for (int32 ValueIndex = 0; ValueIndex < RawData.Num(); ValueIndex++) { - FQuat* QuatValue = reinterpret_cast(RawData[0]); + UE::Math::TQuat* QuatValue = reinterpret_cast*>(RawData[0]); if (QuatValue != NULL) { - const FQuat PreviousValue = *QuatValue; - const FRotator CurrentRotation = QuatValue->Rotator(); + const UE::Math::TQuat PreviousValue = *QuatValue; + const UE::Math::TRotator CurrentRotation = QuatValue->Rotator(); - FRotator Rotation( - CachedRotationPitch->IsSet() ? CachedRotationPitch->Get() : CurrentRotation.Pitch, - CachedRotationYaw->IsSet() ? CachedRotationYaw->Get() : CurrentRotation.Yaw, - CachedRotationRoll->IsSet() ? CachedRotationRoll->Get() : CurrentRotation.Roll + UE::Math::TRotator Rotation( + this->CachedRotationPitch->IsSet() ? this->CachedRotationPitch->Get() : CurrentRotation.Pitch, + this->CachedRotationYaw->IsSet() ? this->CachedRotationYaw->Get() : CurrentRotation.Yaw, + this->CachedRotationRoll->IsSet() ? this->CachedRotationRoll->Get() : CurrentRotation.Roll ); - const FQuat NewValue = Rotation.Quaternion(); + const UE::Math::TQuat NewValue = Rotation.Quaternion(); - // In some cases the FQuat pointed to in RawData is no longer aligned to 16 bytes. - // Make a local copy to guarantee the alignment criterions of the vector intrinsics inside FQuat::Equals - const FQuat AlignedQuatValue = *QuatValue; + // In some cases the UE::Math::TQuat pointed to in RawData is no longer aligned to 16 bytes. + // Make a local copy to guarantee the alignment criterions of the vector intrinsics inside UE::Math::TQuat::Equals + const UE::Math::TQuat AlignedQuatValue = *QuatValue; - if (!bNotifiedPreChange && (!AlignedQuatValue.Equals(NewValue, 0.0f) || (!bIsUsingSlider && bIsInteractiveChangeInProgress))) + if (!bNotifiedPreChange && (!AlignedQuatValue.Equals(NewValue, 0.0f) || (!this->bIsUsingSlider && bIsInteractiveChangeInProgress))) { if (!bIsInteractiveChangeInProgress) { @@ -749,7 +762,7 @@ bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHan PropertyHandle->NotifyPreChange(); bNotifiedPreChange = true; - bIsInteractiveChangeInProgress = bIsUsingSlider; + bIsInteractiveChangeInProgress = this->bIsUsingSlider; } // Set the new value. @@ -757,14 +770,14 @@ bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHan // Propagate default value changes after updating, for archetypes. As per usual, we only propagate the change if the instance matches the archetype's value. // Note: We cannot use the "normal" PropertyNode propagation logic here, because that is string-based and the decision to propagate relies on an exact value match. - // Here, we're dealing with conversions between FQuat and FRotator values, so there is some precision loss that requires a tolerance when comparing values. + // Here, we're dealing with conversions between UE::Math::TQuat and UE::Math::TRotator values, so there is some precision loss that requires a tolerance when comparing values. if (ValueIndex < OuterObjects.Num() && OuterObjects[ValueIndex]->IsTemplate()) { TArray ArchetypeInstances; OuterObjects[ValueIndex]->GetArchetypeInstances(ArchetypeInstances); for (UObject* ArchetypeInstance : ArchetypeInstances) { - FQuat* CurrentValue = reinterpret_cast(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); + UE::Math::TQuat* CurrentValue = reinterpret_cast*>(PropertyHandle->GetValueBaseAddress(reinterpret_cast(ArchetypeInstance))); if (CurrentValue && CurrentValue->Equals(PreviousValue)) { *CurrentValue = NewValue; @@ -776,22 +789,30 @@ bool FQuatStructCustomization::FlushValues(TWeakPtr PropertyHan if (bNotifiedPreChange) { - PropertyHandle->NotifyPostChange(bIsUsingSlider ? EPropertyChangeType::Interactive : EPropertyChangeType::ValueSet); + PropertyHandle->NotifyPostChange(this->bIsUsingSlider ? EPropertyChangeType::Interactive : EPropertyChangeType::ValueSet); - if (!bIsUsingSlider) + if (!this->bIsUsingSlider) { GEditor->EndTransaction(); bIsInteractiveChangeInProgress = false; } } - if (PropertyUtilities.IsValid() && !bIsInteractiveChangeInProgress) + if (this->PropertyUtilities.IsValid() && !bIsInteractiveChangeInProgress) { FPropertyChangedEvent ChangeEvent(PropertyHandle->GetProperty(), EPropertyChangeType::ValueSet, OuterObjects); - PropertyUtilities->NotifyFinishedChangingProperties(ChangeEvent); + this->PropertyUtilities->NotifyFinishedChangingProperties(ChangeEvent); } return true; } +// Instantiate for linker +template class FMatrixStructCustomization; +template class FMatrixStructCustomization; +template class FTransformStructCustomization; +template class FTransformStructCustomization; +template class FQuatStructCustomization; +template class FQuatStructCustomization; + #undef LOCTEXT_NAMESPACE diff --git a/Engine/Source/Editor/DetailCustomizations/Public/Customizations/MathStructProxyCustomizations.h b/Engine/Source/Editor/DetailCustomizations/Public/Customizations/MathStructProxyCustomizations.h index 4cd20c1aeb2e..2c5ea311d58e 100644 --- a/Engine/Source/Editor/DetailCustomizations/Public/Customizations/MathStructProxyCustomizations.h +++ b/Engine/Source/Editor/DetailCustomizations/Public/Customizations/MathStructProxyCustomizations.h @@ -222,9 +222,21 @@ protected: TSharedPtr PropertyUtilities; }; + +struct FTransformField +{ + enum Type + { + Location, + Rotation, + Scale + }; +}; + /** * Proxy struct customization that displays a matrix as a position, rotation & scale. */ +template class DETAILCUSTOMIZATIONS_API FMatrixStructCustomization : public FMathStructProxyCustomization { public: @@ -232,18 +244,18 @@ public: public: FMatrixStructCustomization() - : CachedRotation(MakeShareable( new TProxyValue(FRotator::ZeroRotator))) - , CachedRotationYaw(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Yaw))) - , CachedRotationPitch(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Pitch))) - , CachedRotationRoll(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Roll))) - , CachedTranslation(MakeShareable( new TProxyValue(FVector::ZeroVector))) - , CachedTranslationX(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().X))) - , CachedTranslationY(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().Y))) - , CachedTranslationZ(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().Z))) - , CachedScale(MakeShareable( new TProxyValue(FVector::ZeroVector))) - , CachedScaleX(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().X))) - , CachedScaleY(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().Y))) - , CachedScaleZ(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().Z))) + : CachedRotation(MakeShareable( new TProxyValue>(UE::Math::TRotator::ZeroRotator))) + , CachedRotationYaw(MakeShareable( new TProxyProperty, T>(CachedRotation, CachedRotation->Get().Yaw))) + , CachedRotationPitch(MakeShareable( new TProxyProperty, T>(CachedRotation, CachedRotation->Get().Pitch))) + , CachedRotationRoll(MakeShareable( new TProxyProperty, T>(CachedRotation, CachedRotation->Get().Roll))) + , CachedTranslation(MakeShareable( new TProxyValue>(UE::Math::TVector::ZeroVector))) + , CachedTranslationX(MakeShareable( new TProxyProperty, T>(CachedTranslation, CachedTranslation->Get().X))) + , CachedTranslationY(MakeShareable( new TProxyProperty, T>(CachedTranslation, CachedTranslation->Get().Y))) + , CachedTranslationZ(MakeShareable( new TProxyProperty, T>(CachedTranslation, CachedTranslation->Get().Z))) + , CachedScale(MakeShareable( new TProxyValue>(UE::Math::TVector::ZeroVector))) + , CachedScaleX(MakeShareable( new TProxyProperty, T>(CachedScale, CachedScale->Get().X))) + , CachedScaleY(MakeShareable( new TProxyProperty, T>(CachedScale, CachedScale->Get().Y))) + , CachedScaleZ(MakeShareable( new TProxyProperty, T>(CachedScale, CachedScale->Get().Z))) { } @@ -263,43 +275,34 @@ protected: virtual bool CacheValues(TWeakPtr PropertyHandlePtr) const override; virtual bool FlushValues(TWeakPtr PropertyHandlePtr) const override; - struct FTransformField - { - enum Type - { - Location, - Rotation, - Scale - }; - }; - void OnCopy(FTransformField::Type Type, TWeakPtr PropertyHandlePtr); void OnPaste(FTransformField::Type Type, TWeakPtr PropertyHandlePtr); protected: /** Cached rotation values */ - mutable TSharedRef< TProxyValue > CachedRotation; - mutable TSharedRef< TProxyProperty > CachedRotationYaw; - mutable TSharedRef< TProxyProperty > CachedRotationPitch; - mutable TSharedRef< TProxyProperty > CachedRotationRoll; + mutable TSharedRef< TProxyValue> > CachedRotation; + mutable TSharedRef< TProxyProperty, T> > CachedRotationYaw; + mutable TSharedRef< TProxyProperty, T> > CachedRotationPitch; + mutable TSharedRef< TProxyProperty, T> > CachedRotationRoll; /** Cached translation values */ - mutable TSharedRef< TProxyValue > CachedTranslation; - mutable TSharedRef< TProxyProperty > CachedTranslationX; - mutable TSharedRef< TProxyProperty > CachedTranslationY; - mutable TSharedRef< TProxyProperty > CachedTranslationZ; + mutable TSharedRef< TProxyValue> > CachedTranslation; + mutable TSharedRef< TProxyProperty, T > > CachedTranslationX; + mutable TSharedRef< TProxyProperty, T > > CachedTranslationY; + mutable TSharedRef< TProxyProperty, T> > CachedTranslationZ; /** Cached scale values */ - mutable TSharedRef< TProxyValue > CachedScale; - mutable TSharedRef< TProxyProperty > CachedScaleX; - mutable TSharedRef< TProxyProperty > CachedScaleY; - mutable TSharedRef< TProxyProperty > CachedScaleZ; + mutable TSharedRef< TProxyValue> > CachedScale; + mutable TSharedRef< TProxyProperty, T> > CachedScaleX; + mutable TSharedRef< TProxyProperty, T> > CachedScaleY; + mutable TSharedRef< TProxyProperty, T> > CachedScaleZ; }; /** * Proxy struct customization that displays an FTransform as a position, euler rotation & scale. */ -class FTransformStructCustomization : public FMatrixStructCustomization +template +class FTransformStructCustomization : public FMatrixStructCustomization { public: static TSharedRef MakeInstance(); @@ -313,7 +316,8 @@ protected: /** * Proxy struct customization that displays an FQuat as an euler rotation */ -class DETAILCUSTOMIZATIONS_API FQuatStructCustomization : public FMatrixStructCustomization +template +class DETAILCUSTOMIZATIONS_API FQuatStructCustomization : public FMatrixStructCustomization { public: static TSharedRef MakeInstance();