Files
UnrealEngine/Engine/Source/Editor/MovieSceneTools/Public/Channels/PerlinNoiseChannelInterface.h
2025-05-18 13:04:45 +08:00

212 lines
8.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CurveKeyEditors/SequencerKeyEditor.h"
#include "Framework/MultiBox/MultiBoxExtender.h"
#include "ISequencerChannelInterface.h"
#include "Misc/NotifyHook.h"
#include "MovieSceneSection.h"
#include "TimeToPixel.h"
#include "Widgets/Input/NumericTypeInterface.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Text/STextBlock.h"
class FMenuBuilder;
template<typename ChannelType, typename NumericType>
class SNumericTextBlockKeyEditor : public SCompoundWidget
{
using FKeyEditor = TSequencerKeyEditor<ChannelType, NumericType>;
FKeyEditor KeyEditor;
TSharedPtr<INumericTypeInterface<NumericType>> Interface;
SLATE_BEGIN_ARGS(SNumericTextBlockKeyEditor){}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs, const FKeyEditor& InKeyEditor)
{
KeyEditor = InKeyEditor;
Interface = MakeShareable(new TDefaultNumericTypeInterface<NumericType>);
ChildSlot
[
SNew(STextBlock)
.Text(this, &SNumericTextBlockKeyEditor<ChannelType, NumericType>::GetValueAsText)
];
}
FText GetValueAsText() const
{
const FString ValueString = Interface->ToString(KeyEditor.GetCurrentValue());
return FText::FromString(ValueString);
}
};
struct FPerlinNoiseChannelSectionMenuExtension : TSharedFromThis<FPerlinNoiseChannelSectionMenuExtension>, ISidebarChannelExtension
{
FPerlinNoiseChannelSectionMenuExtension(TArrayView<const FMovieSceneChannelHandle> InChannelHandles, const TArray<TWeakObjectPtr<UMovieSceneSection>>& InWeakSections);
virtual ~FPerlinNoiseChannelSectionMenuExtension() {}
virtual TSharedPtr<ISidebarChannelExtension> ExtendMenu(FMenuBuilder& MenuBuilder, const bool bInSubMenu) override;
private:
void Initialize();
void BuildChannelsMenu(FMenuBuilder& MenuBuilder);
void BuildParametersMenu(FMenuBuilder& MenuBuilder, int32 ChannelHandleIndex);
private:
struct FChannelNotifyHook : FNotifyHook
{
TWeakObjectPtr<UObject> WeakObjectToModify;
FChannelNotifyHook(UObject* InObjectToModify) : WeakObjectToModify(InObjectToModify) {}
virtual void NotifyPreChange(FProperty* PropertyAboutToChange) override;
virtual void NotifyPostChange(const FPropertyChangedEvent& PropertyChangedEvent, FProperty* PropertyThatChanged) override;
};
TArray<FMovieSceneChannelHandle> ChannelHandles;
TArray<int32> ChannelHandleSectionIndexes;
TArray<TWeakObjectPtr<UMovieSceneSection>> WeakSections;
TArray<FChannelNotifyHook> NotifyHooks;
};
template<typename ChannelContainerType>
struct TPerlinNoiseChannelInterface : ISequencerChannelInterface
{
using ChannelType = typename ChannelContainerType::ChannelType;
virtual FKeyHandle AddOrUpdateKey_Raw(FMovieSceneChannel* Channel, UMovieSceneSection* SectionToKey, const void* ExtendedEditorData, FFrameNumber InTime, ISequencer& InSequencer, const FGuid& ObjectBindingID, FTrackInstancePropertyBindings* PropertyBindings) const override
{
return FKeyHandle::Invalid();
}
virtual void DeleteKeys_Raw(FMovieSceneChannel* Channel, TArrayView<const FKeyHandle> InHandles, FFrameNumber InTime) const override
{
}
virtual void CopyKeys_Raw(FMovieSceneChannel* Channel, const UMovieSceneSection* Section, FName KeyAreaName, FMovieSceneClipboardBuilder& ClipboardBuilder, TArrayView<const FKeyHandle> KeyMask) const override
{
}
virtual void PasteKeys_Raw(FMovieSceneChannel* Channel, UMovieSceneSection* Section, const FMovieSceneClipboardKeyTrack& KeyTrack, const FMovieSceneClipboardEnvironment& SrcEnvironment, const FSequencerPasteEnvironment& DstEnvironment, TArray<FKeyHandle>& OutPastedKeys) const override
{
}
virtual TSharedPtr<FStructOnScope> GetKeyStruct_Raw(FMovieSceneChannelHandle Channel, FKeyHandle KeyHandle) const override
{
return nullptr;
}
virtual bool CanCreateKeyEditor_Raw(const FMovieSceneChannel* Channel) const override
{
return true;
}
virtual TSharedRef<SWidget> CreateKeyEditor_Raw(const FMovieSceneChannelHandle& Channel, const UE::Sequencer::FCreateKeyEditorParams& Params) const override
{
const TMovieSceneExternalValue<typename ChannelType::CurveValueType>* ExternalValue = Channel.Cast<ChannelType>().GetExtendedEditorData();
if (!ExternalValue)
{
return SNullWidget::NullWidget;
}
TSequencerKeyEditor<ChannelType, typename ChannelType::CurveValueType> KeyEditor(
Params.ObjectBindingID, Channel.Cast<ChannelType>(),
Params.OwningSection, Params.Sequencer, Params.PropertyBindings, ExternalValue->OnGetExternalValue
);
using KeyEditorType = SNumericTextBlockKeyEditor<ChannelType, typename ChannelType::CurveValueType>;
return SNew(KeyEditorType, KeyEditor);
}
virtual void ExtendKeyMenu_Raw(FMenuBuilder& MenuBuilder, TSharedPtr<FExtender> MenuExtender, TArrayView<const FExtendKeyMenuParams> Parameters, TWeakPtr<ISequencer> InSequencer) const override
{
}
virtual void ExtendSectionMenu_Raw(FMenuBuilder& MenuBuilder, TSharedPtr<FExtender> InMenuExtender, TArrayView<const FMovieSceneChannelHandle> InChannels, const TArray<TWeakObjectPtr<UMovieSceneSection>>& InWeakSections, TWeakPtr<ISequencer> InWeakSequencer) const override
{
TSharedRef<FPerlinNoiseChannelSectionMenuExtension> Extension = MakeShared<FPerlinNoiseChannelSectionMenuExtension>(InChannels, InWeakSections);
InMenuExtender->AddMenuExtension(TEXT("SequencerChannels"), EExtensionHook::First, nullptr
, FMenuExtensionDelegate::CreateLambda([Extension](FMenuBuilder& MenuBuilder)
{
Extension->ExtendMenu(MenuBuilder, true);
}));
}
virtual TSharedPtr<ISidebarChannelExtension> ExtendSidebarMenu_Raw(FMenuBuilder& MenuBuilder, TSharedPtr<FExtender> InMenuExtender, TArrayView<const FMovieSceneChannelHandle> InChannels, const TArray<TWeakObjectPtr<UMovieSceneSection>>& InWeakSections, TWeakPtr<ISequencer> InWeakSequencer) const override
{
const TSharedRef<FPerlinNoiseChannelSectionMenuExtension> Extension = MakeShared<FPerlinNoiseChannelSectionMenuExtension>(InChannels, InWeakSections);
Extension->ExtendMenu(MenuBuilder, false);
return Extension;
}
virtual void DrawKeys_Raw(FMovieSceneChannel* Channel, TArrayView<const FKeyHandle> InKeyHandles, const UMovieSceneSection* InOwner, TArrayView<FKeyDrawParams> OutKeyDrawParams) const override
{
}
virtual bool ShouldShowCurve_Raw(const FMovieSceneChannel* Channel, UMovieSceneSection* InSection) const override
{
return true;
}
virtual bool SupportsCurveEditorModels_Raw(const FMovieSceneChannelHandle& InChannel) const override
{
return false;
}
virtual TUniquePtr<FCurveModel> CreateCurveEditorModel_Raw(const FMovieSceneChannelHandle& Channel, const UE::Sequencer::FCreateCurveEditorModelParams& Params) const override
{
return nullptr;
}
virtual int32 DrawExtra_Raw(FMovieSceneChannel* InChannel, const UMovieSceneSection* InOwner, const FSequencerChannelPaintArgs& PaintArgs, int32 LayerId) const override
{
using namespace UE::Sequencer;
FLinearColor FillColor(1, 1, 1, 0.334f);
ChannelType* TypedChannel = static_cast<ChannelType*>(InChannel);
TArray<FVector2D> CurvePoints;
CurvePoints.Reserve(PaintArgs.Geometry.Size.X / 2.0);
const double Amplitude = TypedChannel->PerlinNoiseParams.Amplitude;
const double YOffset = PaintArgs.Geometry.Size.Y / 2.0;
const double YScale = (Amplitude != 0) ? (PaintArgs.Geometry.Size.Y / Amplitude / 2.0) : 1;
for (double X = 0; X < PaintArgs.Geometry.Size.X; X += 2.f)
{
double Seconds = PaintArgs.TimeToPixel.PixelToSeconds(X);
double Y = (double)TypedChannel->Evaluate(Seconds);
CurvePoints.Add(FVector2D(X, YOffset - (Y * YScale)));
}
FSlateDrawElement::MakeLines(
PaintArgs.DrawElements,
LayerId,
PaintArgs.Geometry.ToPaintGeometry(),
CurvePoints,
ESlateDrawEffect::PreMultipliedAlpha,
FillColor,
true);
return LayerId + 1;
}
virtual TSharedPtr<UE::Sequencer::FChannelModel> CreateChannelModel_Raw(const FMovieSceneChannelHandle& InChannelHandle, const UE::Sequencer::FSectionModel& InSection, FName InChannelName) const override
{
return nullptr;
}
virtual TSharedPtr<UE::Sequencer::STrackAreaLaneView> CreateChannelView_Raw(const FMovieSceneChannelHandle& InChannelHandle, TWeakPtr<UE::Sequencer::FChannelModel> InWeakModel, const UE::Sequencer::FCreateTrackLaneViewParams& Parameters) const override
{
return nullptr;
}
};