Files
UnrealEngineUWP/Engine/Source/Editor/CurveEditor/Private/SCurveViewerPanel.cpp
andrew rodham 927c5d41b3 Sequencer: Added time-warp capabilities to sequences, sub-sections and skeletal animation sections
This is a large suite of changes that are being submitted in bulk for build-health reasons:

Core machinery:
 - FMovieSceneNumericVariant: This is the base variant type that represents either a double, or a custom object. It is not much use on its own, but provides the basis for the time-warp variant, and will be the basis for parameterization.
 - FMovieSceneTimeWarpVariant: This is a drop in replacement for a double PlayRate/TimeScale UProperty that can now represent a time-warp or play rate curve, a loop, a clamp, or a fixed time. It also provides functionality for remapping time, and inverse remapping time.
 - The following interpolation types have been added/improved to add Derivative and Integral functionality
   * FConstantValue: Represents a curve of the form y=c
   * FLinearInterpolation: Represents a curve of the form y=mx + c
   * FQuadraticInterpolation: Represents a curve of the form y=ax^2 + bx + c.
   * FCubicInterpolation: Represents a curve of the form y=ax^3 + bx^2 + cx + d.
   * FQuarticInterpolation: Represents a curve of the form y=ax^4 + bx^3 + cx^2 + dx + e. Does not support integration.
   * FCubicBezierInterpolation now has an AsCubic method that converts it to a cubic polynomial form, which also allows derivative/integral functionality.
 - FPiecewiseCurve(Model): A generic read-only piecewise curve implementation and curve editor model. Used to display derivative curves for playrate.
 - FMovieSceneTimingParameters: A struct for specifying section timing that simplifies computation of a transform. I wanted to replace all implementations with this but current deprecation mechanisms were prohibitively restrictive. More work will be needed there to remove legacy code.
 - FMovieSceneTimeWarpChannel: A new channel type that defines time in one of two domains: PlayRate or Time

Curve Editor: Added the ability to specify custom axes and child curves
- Custom Axes:
  * Custom axes can now be assigned to each curve within a view, and the axis defines the scaling for that curve.
  * This allows us to have multiple different 'spaces' on the same view that have vastly different scales (for instance, play rate, and tick resolution times)
- Child Curves:
  * Child curves are added whenever their parent is added. This allows us to show the derivative of a play rate curve on the curve editor.

Sequencer: Added Owning Object and key offsets to channel meta-data and curve models, made Sequencer key-editors polymorphic,
- New options on channel proxy entries allow us to specify that a channel's keys are relative to their section start time via a key offset
- New options in the curve editor models allow for a non-UMovieSceneSection owner object type

#jira UE-149871
#rb Ludovic.Chabant, David.Bromberg, Max.Chen

[CL 34813298 by andrew rodham in ue5-main branch]
2024-07-15 10:52:09 -04:00

136 lines
4.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SCurveViewerPanel.h"
#include "Containers/Map.h"
#include "Containers/SortedMap.h"
#include "CurveDrawInfo.h"
#include "CurveEditor.h"
#include "CurveEditorTypes.h"
#include "Layout/Clipping.h"
#include "Layout/Geometry.h"
#include "Layout/PaintGeometry.h"
#include "Math/Color.h"
#include "Math/UnrealMathSSE.h"
#include "Math/Vector2D.h"
#include "Misc/Attribute.h"
#include "Misc/Optional.h"
#include "Rendering/DrawElements.h"
#include "Templates/Less.h"
#include "Templates/UniquePtr.h"
#include "Views/SInteractiveCurveEditorView.h"
class FCurveModel;
class FPaintArgs;
class FSlateRect;
class FWidgetStyle;
#define LOCTEXT_NAMESPACE "SCurveViewerPanel"
namespace CurveViewerConstants
{
static bool bAntiAliasCurves = true;
}
void SCurveViewerPanel::Construct(const FArguments& InArgs, TSharedRef<FCurveEditor> InCurveEditor)
{
WeakCurveEditor = InCurveEditor;
CurveThickness = InArgs._CurveThickness;
InCurveEditor->SetView(SharedThis(this));
CachedValues.CachedTangentVisibility = InCurveEditor->GetSettings()->GetTangentVisibility();
for (const TPair<FCurveModelID, TUniquePtr<FCurveModel>>& CurvePair : InCurveEditor->GetCurves())
{
CurveInfoByID.Add(CurvePair.Key);
}
SetClipping(EWidgetClipping::ClipToBounds);
}
void SCurveViewerPanel::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
CachedDrawParams.Reset();
GetCurveDrawParams(CachedDrawParams);
}
int32 SCurveViewerPanel::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
const ESlateDrawEffect DrawEffects = ShouldBeEnabled(bParentEnabled) ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;
DrawCurves(AllottedGeometry, OutDrawElements, LayerId, InWidgetStyle, DrawEffects);
return LayerId + CurveViewConstants::ELayerOffset::Last;
}
void SCurveViewerPanel::DrawCurves(const FGeometry& AllottedGeometry, FSlateWindowElementList& OutDrawElements, int32 BaseLayerId, const FWidgetStyle& InWidgetStyle, ESlateDrawEffect DrawEffects) const
{
const FPaintGeometry PaintGeometry = AllottedGeometry.ToPaintGeometry();
float DashOffset = static_cast<float>(GetViewSpace().PixelsPerInput() * GetViewSpace().GetInputMin());
for (const FCurveDrawParams& Params : CachedDrawParams)
{
if (Params.DashLengthPx > 0.f)
{
TArray<FVector2f> NewVector;
NewVector.Reserve(Params.InterpolatingPoints.Num());
for (FVector2d Vect : Params.InterpolatingPoints)
{
NewVector.Add(UE::Slate::CastToVector2f(Vect));
}
FSlateDrawElement::MakeDashedLines(
OutDrawElements,
BaseLayerId + CurveViewConstants::ELayerOffset::Curves,
PaintGeometry,
MoveTemp(NewVector),
DrawEffects,
Params.Color,
CurveThickness.Get(),
Params.DashLengthPx,
DashOffset
);
}
else
{
FSlateDrawElement::MakeLines(
OutDrawElements,
BaseLayerId + CurveViewConstants::ELayerOffset::Curves,
PaintGeometry,
Params.InterpolatingPoints,
DrawEffects,
Params.Color,
CurveViewerConstants::bAntiAliasCurves,
CurveThickness.Get()
);
}
if (Params.bKeyDrawEnabled)
{
for (int32 PointIndex = 0; PointIndex < Params.Points.Num(); PointIndex++)
{
const FCurvePointInfo& Point = Params.Points[PointIndex];
const FKeyDrawInfo& PointDrawInfo = Params.GetKeyDrawInfo(Point.Type, PointIndex);
const int32 KeyLayerId = BaseLayerId + Point.LayerBias + CurveViewConstants::ELayerOffset::Keys;
FLinearColor PointTint = PointDrawInfo.Tint.IsSet() ? PointDrawInfo.Tint.GetValue() : Params.Color;
// Brighten and saturate the points a bit so they pop
FLinearColor HSV = PointTint.LinearRGBToHSV();
HSV.G = FMath::Clamp(HSV.G * 1.1f, 0.f, 255.f);
HSV.B = FMath::Clamp(HSV.B * 2.f, 0.f, 255.f);
PointTint = HSV.HSVToLinearRGB();
FPaintGeometry PointGeometry = AllottedGeometry.ToPaintGeometry(
PointDrawInfo.ScreenSize,
FSlateLayoutTransform(Point.ScreenPosition - (PointDrawInfo.ScreenSize * 0.5f))
);
FSlateDrawElement::MakeBox(OutDrawElements, KeyLayerId, PointGeometry, PointDrawInfo.Brush, DrawEffects, PointTint );
}
}
}
}
#undef LOCTEXT_NAMESPACE