Files
UnrealEngineUWP/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScriptingEditor/Private/SequencerTools.cpp

806 lines
31 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
#include "SequencerTools.h"
#include "SequencerScriptingEditor.h"
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
#include "MovieSceneCapture.h"
#include "MovieSceneCaptureDialogModule.h"
#include "AutomatedLevelSequenceCapture.h"
#include "MovieSceneTimeHelpers.h"
#include "UObject/Stack.h"
#include "UObject/Package.h"
#include "LevelSequenceActor.h"
#include "LevelSequencePlayer.h"
#include "FbxExporter.h"
#include "FbxImporter.h"
#include "MovieSceneToolsUserSettings.h"
#include "MovieSceneToolHelpers.h"
#include "MovieSceneEventUtils.h"
#include "MovieSceneSequenceEditor.h"
#include "Sections/MovieSceneEventSectionBase.h"
#include "CineCameraActor.h"
#include "CineCameraComponent.h"
#include "MovieSceneCommonHelpers.h"
#include "Components/SkeletalMeshComponent.h"
#include "Animation/AnimSequenceBase.h"
#include "ScopedTransaction.h"
#include "Exporters/AnimSeqExportOption.h"
#include "K2Node_CustomEvent.h"
#include "BlueprintFunctionNodeSpawner.h"
#include "BlueprintActionMenuItem.h"
#include "EdGraphSchema_K2.h"
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
#include "AssetRegistry/AssetData.h"
#include "LevelSequenceAnimSequenceLink.h"
#include "AnimSequenceLevelSequenceLink.h"
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
#define LOCTEXT_NAMESPACE "SequencerTools"
bool USequencerToolsFunctionLibrary::RenderMovie(UMovieSceneCapture* InCaptureSettings, FOnRenderMovieStopped OnFinishedCallback)
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
{
IMovieSceneCaptureDialogModule& MovieSceneCaptureModule = FModuleManager::Get().LoadModuleChecked<IMovieSceneCaptureDialogModule>("MovieSceneCaptureDialog");
// Because this comes from the Python/BP layer we need to soft-validate the state before we pass it onto functions that do a assert-based validation.
if (!InCaptureSettings)
{
FFrame::KismetExecutionMessage(TEXT("Cannot start Render Sequence to Movie with null capture settings."), ELogVerbosity::Error);
return false;
}
if (IsRenderingMovie())
{
FFrame::KismetExecutionMessage(TEXT("Capture already in progress."), ELogVerbosity::Error);
return false;
}
// If they're capturing a level sequence we'll do some additional checking as there are more parameters on the Automated Level Sequence capture.
UAutomatedLevelSequenceCapture* LevelSequenceCapture = Cast<UAutomatedLevelSequenceCapture>(InCaptureSettings);
if (LevelSequenceCapture)
{
if (!LevelSequenceCapture->LevelSequenceAsset.IsValid())
{
// UE_LOG(LogTemp, Warning, TEXT("No Level Sequence Asset specified in UAutomatedLevelSequenceCapture."));
FFrame::KismetExecutionMessage(TEXT("No Level Sequence Asset specified in UAutomatedLevelSequenceCapture."), ELogVerbosity::Error);
return false;
}
if (!LevelSequenceCapture->bUseCustomStartFrame && !LevelSequenceCapture->bUseCustomEndFrame)
{
// If they don't want to use a custom start/end frame we override the default values to be the length of the sequence, as the default is [0,1)
ULevelSequence* LevelSequence = Cast<ULevelSequence>(LevelSequenceCapture->LevelSequenceAsset.TryLoad());
if (!LevelSequence)
{
const FString ErrorMessage = FString::Printf(TEXT("Specified Level Sequence Asset failed to load. Specified Asset Path: %s"), *LevelSequenceCapture->LevelSequenceAsset.GetAssetPathString());
FFrame::KismetExecutionMessage(*ErrorMessage, ELogVerbosity::Error);
return false;
}
FFrameRate DisplayRate = LevelSequence->GetMovieScene()->GetDisplayRate();
FFrameRate TickResolution = LevelSequence->GetMovieScene()->GetTickResolution();
LevelSequenceCapture->Settings.CustomFrameRate = DisplayRate;
LevelSequenceCapture->Settings.bUseCustomFrameRate = true;
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
LevelSequenceCapture->Settings.bUseRelativeFrameNumbers = false;
TRange<FFrameNumber> Range = LevelSequence->GetMovieScene()->GetPlaybackRange();
FFrameNumber StartFrame = UE::MovieScene::DiscreteInclusiveLower(Range);
FFrameNumber EndFrame = UE::MovieScene::DiscreteExclusiveUpper(Range);
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
FFrameNumber RoundedStartFrame = FFrameRate::TransformTime(StartFrame, TickResolution, DisplayRate).CeilToFrame();
FFrameNumber RoundedEndFrame = FFrameRate::TransformTime(EndFrame, TickResolution, DisplayRate).CeilToFrame();
LevelSequenceCapture->CustomStartFrame = RoundedStartFrame;
LevelSequenceCapture->CustomEndFrame = RoundedEndFrame;
}
}
auto LocalCaptureStoppedCallback = [OnFinishedCallback](bool bSuccess)
{
OnFinishedCallback.ExecuteIfBound(bSuccess);
};
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
MovieSceneCaptureModule.StartCapture(InCaptureSettings);
MovieSceneCaptureModule.GetCurrentCapture()->CaptureStoppedDelegate.AddLambda(LocalCaptureStoppedCallback);
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
return true;
}
void USequencerToolsFunctionLibrary::CancelMovieRender()
{
IMovieSceneCaptureDialogModule& MovieSceneCaptureModule = FModuleManager::Get().LoadModuleChecked<IMovieSceneCaptureDialogModule>("MovieSceneCaptureDialog");
TSharedPtr<FMovieSceneCaptureBase> CurrentCapture = MovieSceneCaptureModule.GetCurrentCapture();
if (CurrentCapture.IsValid())
{
// We just invoke the capture's Cancel function. This will cause a shut-down of the capture (the same as the UI)
// which will invoke all of the necessary callbacks as well. We don't null out CurrentCapture because that is done
// as the result of its shutdown callbacks.
CurrentCapture->Cancel();
}
}
TArray<FSequencerBoundObjects> USequencerToolsFunctionLibrary::GetBoundObjects(UWorld* InWorld, ULevelSequence* InSequence, const TArray<FSequencerBindingProxy>& InBindings, const FSequencerScriptingRange& InRange)
{
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(InWorld, InSequence, Settings, OutActor);
Player->Initialize(InSequence, InWorld->PersistentLevel, Settings, CameraSettings);
Player->State.AssignSequence(MovieSceneSequenceID::Root, *InSequence, *Player);
// Evaluation needs to occur in order to obtain spawnables
FFrameRate Resolution = InSequence->GetMovieScene()->GetTickResolution();
TRange<FFrameNumber> SpecifiedRange = InRange.ToNative(Resolution);
Player->SetPlaybackPosition(FMovieSceneSequencePlaybackParams(SpecifiedRange.GetLowerBoundValue().Value, EUpdatePositionMethod::Play));
FMovieSceneSequenceID SequenceId = Player->State.FindSequenceId(InSequence);
TArray<FSequencerBoundObjects> BoundObjects;
for (FSequencerBindingProxy Binding : InBindings)
{
FMovieSceneObjectBindingID ObjectBinding = UE::MovieScene::FFixedObjectBindingID(Binding.BindingID, SequenceId);
BoundObjects.Add(FSequencerBoundObjects(Binding, Player->GetBoundObjects(ObjectBinding)));
}
Player->Stop();
InWorld->DestroyActor(OutActor);
return BoundObjects;
}
TArray<FSequencerBoundObjects> USequencerToolsFunctionLibrary::GetObjectBindings(UWorld* InWorld, ULevelSequence* InSequence, const TArray<UObject*>& InObjects, const FSequencerScriptingRange& InRange)
{
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(InWorld, InSequence, Settings, OutActor);
Player->Initialize(InSequence, InWorld->PersistentLevel, Settings, CameraSettings);
Player->State.AssignSequence(MovieSceneSequenceID::Root, *InSequence, *Player);
FFrameRate Resolution = InSequence->GetMovieScene()->GetTickResolution();
TRange<FFrameNumber> SpecifiedRange = InRange.ToNative(Resolution);
Player->SetPlaybackPosition(FMovieSceneSequencePlaybackParams(SpecifiedRange.GetLowerBoundValue().Value, EUpdatePositionMethod::Play));
TArray<FSequencerBoundObjects> BoundObjects;
for (UObject* Object : InObjects)
{
TArray<FMovieSceneObjectBindingID> ObjectBindings = Player->GetObjectBindings(Object);
for (FMovieSceneObjectBindingID ObjectBinding : ObjectBindings)
{
FMovieSceneSequenceID SequenceID = ObjectBinding.ResolveSequenceID(MovieSceneSequenceID::Root, *Player);
FSequencerBindingProxy Binding(ObjectBinding.GetGuid(), Player->State.FindSequence(SequenceID));
BoundObjects.Add(FSequencerBoundObjects(Binding, TArray<UObject*>({ Object })));
}
}
Player->Stop();
InWorld->DestroyActor(OutActor);
return BoundObjects;
}
void GatherDescendantBindings(const FSequencerBindingProxy& Binding, UMovieSceneSequence* Sequence, TArray<FSequencerBindingProxy>& AllBindings)
{
UMovieScene* MovieScene = Sequence->GetMovieScene();
for (int32 Index = 0; Index < MovieScene->GetPossessableCount(); ++Index)
{
FMovieScenePossessable& Possessable = MovieScene->GetPossessable(Index);
if (Possessable.GetParent() == Binding.BindingID)
{
FSequencerBindingProxy ChildBinding(Possessable.GetGuid(), Sequence);
AllBindings.Add(ChildBinding);
GatherDescendantBindings(ChildBinding, Sequence, AllBindings);
}
}
}
bool ExportFBXInternal(UWorld* World, UMovieSceneSequence* Sequence, const TArray<FSequencerBindingProxy>& InBindings, const TArray<UMovieSceneTrack*>& MasterTracks, UFbxExportOption* OverrideOptions, const FString& InFBXFileName, UMovieSceneSequencePlayer* Player)
{
UnFbx::FFbxExporter* Exporter = UnFbx::FFbxExporter::GetInstance();
//Show the fbx export dialog options
Exporter->SetExportOptionsOverride(OverrideOptions);
UMovieScene* MovieScene = Sequence->GetMovieScene();
TArray<FSequencerBindingProxy> AllBindings;
for (const FSequencerBindingProxy& Binding : InBindings)
{
AllBindings.Add(Binding);
GatherDescendantBindings(Binding, Sequence, AllBindings);
}
TArray<FGuid> Bindings;
for (const FSequencerBindingProxy& Proxy : AllBindings)
{
if (Proxy.Sequence == Sequence)
{
Bindings.Add(Proxy.BindingID);
}
}
INodeNameAdapter NodeNameAdapter;
Player->State.AssignSequence(MovieSceneSequenceID::Root, *Sequence, *Player);
FMovieSceneSequenceIDRef Template = MovieSceneSequenceID::Root;
bool bDidExport = false;
FMovieSceneSequenceTransform RootToLocalTransform;
{
FSpawnableRestoreState SpawnableRestoreState(MovieScene);
if (SpawnableRestoreState.bWasChanged)
{
// Evaluate at the beginning of the subscene time to ensure that spawnables are created before export
Player->SetPlaybackPosition(FMovieSceneSequencePlaybackParams(UE::MovieScene::DiscreteInclusiveLower(MovieScene->GetPlaybackRange()).Value, EUpdatePositionMethod::Play));
}
bDidExport = MovieSceneToolHelpers::ExportFBX(World, MovieScene, Player, Bindings, MasterTracks, NodeNameAdapter, Template, InFBXFileName, RootToLocalTransform);
}
Player->Stop();
Exporter->SetExportOptionsOverride(nullptr);
return bDidExport;
}
bool USequencerToolsFunctionLibrary::ExportLevelSequenceFBX(UWorld* World, ULevelSequence* Sequence, const TArray<FSequencerBindingProxy>& InBindings, const TArray<UMovieSceneTrack*>& InMasterTracks, UFbxExportOption* OverrideOptions, const FString& InFBXFileName)
{
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(World, Sequence, Settings, OutActor);
Player->Initialize(Sequence, World->PersistentLevel, Settings, CameraSettings);
bool bSuccess = ExportFBXInternal(World, Sequence, InBindings, InMasterTracks, OverrideOptions, InFBXFileName, Player);
World->DestroyActor(OutActor);
return bSuccess;
}
static USkeletalMeshComponent* GetSkelMeshComponent(IMovieScenePlayer* Player, const FSequencerBindingProxy& Binding)
{
FMovieSceneSequenceIDRef Template = MovieSceneSequenceID::Root;
for (TWeakObjectPtr<UObject> RuntimeObject : Player->FindBoundObjects(Binding.BindingID, Template))
{
if (AActor* Actor = Cast<AActor>(RuntimeObject.Get()))
{
for (UActorComponent* Component : Actor->GetComponents())
{
if (USkeletalMeshComponent* SkeletalMeshComp = Cast<USkeletalMeshComponent>(Component))
{
return SkeletalMeshComp;
}
}
}
else if (USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>(RuntimeObject.Get()))
{
if (SkeletalMeshComponent->SkeletalMesh)
{
return SkeletalMeshComponent;
}
}
}
return nullptr;
}
bool USequencerToolsFunctionLibrary::ExportAnimSequence(UWorld* World, ULevelSequence* Sequence, UAnimSequence* AnimSequence, UAnimSeqExportOption* ExportOptions,const FSequencerBindingProxy& Binding, bool bCreateLink)
{
UMovieScene* MovieScene = Sequence->GetMovieScene();
if (Binding.Sequence != Sequence || !AnimSequence)
{
return false;
}
INodeNameAdapter NodeNameAdapter;
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
FMovieSceneSequenceIDRef Template = MovieSceneSequenceID::Root;
FMovieSceneSequenceTransform RootToLocalTransform;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(World, Sequence, Settings, OutActor);
Player->Initialize(Sequence, World->PersistentLevel, Settings, CameraSettings);
Player->State.AssignSequence(MovieSceneSequenceID::Root, *Sequence, *Player);
bool bResult = false;
{
FSpawnableRestoreState SpawnableRestoreState(MovieScene);
if (SpawnableRestoreState.bWasChanged)
{
// Evaluate at the beginning of the subscene time to ensure that spawnables are created before export
Player->SetPlaybackPosition(FMovieSceneSequencePlaybackParams(UE::MovieScene::DiscreteInclusiveLower(MovieScene->GetPlaybackRange()).Value, EUpdatePositionMethod::Play));
}
USkeletalMeshComponent* SkeletalMeshComp = GetSkelMeshComponent(Player, Binding);
if (SkeletalMeshComp && SkeletalMeshComp->SkeletalMesh && SkeletalMeshComp->SkeletalMesh->GetSkeleton())
{
AnimSequence->SetSkeleton(SkeletalMeshComp->SkeletalMesh->GetSkeleton());
bResult = MovieSceneToolHelpers::ExportToAnimSequence(AnimSequence,ExportOptions, MovieScene, Player, SkeletalMeshComp, Template, RootToLocalTransform);
}
}
Player->Stop();
World->DestroyActor(OutActor);
//create the link to the anim sequence
if (bResult && bCreateLink)
{
//create from anim sequence back to level sequence
if (IInterface_AssetUserData* AnimAssetUserData = Cast< IInterface_AssetUserData >(AnimSequence))
{
UAnimSequenceLevelSequenceLink* AnimLevelLink = AnimAssetUserData->GetAssetUserData< UAnimSequenceLevelSequenceLink >();
if (!AnimLevelLink)
{
AnimLevelLink = NewObject<UAnimSequenceLevelSequenceLink>(AnimSequence, NAME_None, RF_Public | RF_Transactional);
AnimAssetUserData->AddAssetUserData(AnimLevelLink);
}
AnimLevelLink->SetLevelSequence(Sequence);
AnimLevelLink->SkelTrackGuid = Binding.BindingID;
}
//create from level sequence to anim sequence, trickier since we can have multiples here.
if (IInterface_AssetUserData* AssetUserDataInterface = Cast< IInterface_AssetUserData >(Sequence))
{
bool bAddItem = true;
ULevelSequenceAnimSequenceLink* LevelAnimLink = AssetUserDataInterface->GetAssetUserData< ULevelSequenceAnimSequenceLink >();
if (LevelAnimLink)
{
for (FLevelSequenceAnimSequenceLinkItem& LevelAnimLinkItem : LevelAnimLink->AnimSequenceLinks)
{
if (LevelAnimLinkItem.SkelTrackGuid == Binding.BindingID)
{
bAddItem = false;
UAnimSequence* OtherAnimSequence = LevelAnimLinkItem.ResolveAnimSequence();
if (OtherAnimSequence != AnimSequence)
{
if (IInterface_AssetUserData* OtherAnimAssetUserData = Cast< IInterface_AssetUserData >(OtherAnimSequence))
{
UAnimSequenceLevelSequenceLink* OtherAnimLevelLink = OtherAnimAssetUserData->GetAssetUserData< UAnimSequenceLevelSequenceLink >();
if (OtherAnimLevelLink)
{
OtherAnimAssetUserData->RemoveUserDataOfClass(UAnimSequenceLevelSequenceLink::StaticClass());
}
}
}
LevelAnimLinkItem.PathToAnimSequence = FSoftObjectPath(AnimSequence);
LevelAnimLinkItem.bExportMorphTargets = ExportOptions->bExportMorphTargets;
LevelAnimLinkItem.bExportAttributeCurves = ExportOptions->bExportAttributeCurves;
LevelAnimLinkItem.bExportMaterialCurves = ExportOptions->bExportMaterialCurves;
LevelAnimLinkItem.bExportTransforms = ExportOptions->bExportTransforms;
LevelAnimLinkItem.bRecordInWorldSpace = ExportOptions->bRecordInWorldSpace;
break;
}
}
}
else
{
LevelAnimLink = NewObject<ULevelSequenceAnimSequenceLink>(Sequence, NAME_None, RF_Public | RF_Transactional);
}
if (bAddItem == true)
{
FLevelSequenceAnimSequenceLinkItem LevelAnimLinkItem;
LevelAnimLinkItem.SkelTrackGuid = Binding.BindingID;
LevelAnimLinkItem.PathToAnimSequence = FSoftObjectPath(AnimSequence);
LevelAnimLinkItem.bExportMorphTargets = ExportOptions->bExportMorphTargets;
LevelAnimLinkItem.bExportAttributeCurves = ExportOptions->bExportAttributeCurves;
LevelAnimLinkItem.bExportMaterialCurves = ExportOptions->bExportMaterialCurves;
LevelAnimLinkItem.bExportTransforms = ExportOptions->bExportTransforms;
LevelAnimLinkItem.bRecordInWorldSpace = ExportOptions->bRecordInWorldSpace;
LevelAnimLink->AnimSequenceLinks.Add(LevelAnimLinkItem);
AssetUserDataInterface->AddAssetUserData(LevelAnimLink);
}
}
}
return bResult;
}
UAnimSequenceLevelSequenceLink* USequencerToolsFunctionLibrary::GetLevelSequenceLinkFromAnimSequence(UAnimSequence* InAnimSequence)
{
if (IInterface_AssetUserData* AnimAssetUserData = Cast< IInterface_AssetUserData >(InAnimSequence))
{
UAnimSequenceLevelSequenceLink* AnimLevelLink = AnimAssetUserData->GetAssetUserData< UAnimSequenceLevelSequenceLink >();
return AnimLevelLink;
}
return nullptr;
}
ULevelSequenceAnimSequenceLink* USequencerToolsFunctionLibrary::GetAnimSequenceLinkFromLevelSequence(ULevelSequence* InLevelSequence)
{
if (IInterface_AssetUserData* AssetUserDataInterface = Cast< IInterface_AssetUserData >(InLevelSequence))
{
ULevelSequenceAnimSequenceLink* LevelAnimLink = AssetUserDataInterface->GetAssetUserData< ULevelSequenceAnimSequenceLink >();
return LevelAnimLink;
}
return nullptr;
}
TArray<FGuid> AddActors(UWorld* World, UMovieSceneSequence* InSequence, UMovieScene* InMovieScene, IMovieScenePlayer* Player, FMovieSceneSequenceIDRef TemplateID,const TArray<TWeakObjectPtr<AActor> >& InActors)
{
TArray<FGuid> PossessableGuids;
if (InMovieScene->IsReadOnly())
{
return PossessableGuids;
}
for (TWeakObjectPtr<AActor> WeakActor : InActors)
{
if (AActor* Actor = WeakActor.Get())
{
FGuid ExistingGuid = Player->FindObjectId(*Actor, TemplateID);
if (!ExistingGuid.IsValid())
{
InMovieScene->Modify();
const FGuid PossessableGuid = InMovieScene->AddPossessable(Actor->GetActorLabel(), Actor->GetClass());
PossessableGuids.Add(PossessableGuid);
InSequence->BindPossessableObject(PossessableGuid, *Actor, World);
//TODO New to figure way to call void FLevelSequenceEditorToolkit::AddDefaultTracksForActor(AActor& Actor, const FGuid Binding)
if (Actor->IsA<ACameraActor>())
{
MovieSceneToolHelpers::CreateCameraCutSectionForCamera(InMovieScene, PossessableGuid, 0);
}
}
}
}
return PossessableGuids;
}
void ImportFBXCamera(UnFbx::FFbxImporter* FbxImporter, UWorld* World, UMovieSceneSequence* Sequence, UMovieScene* InMovieScene, IMovieScenePlayer* Player, FMovieSceneSequenceIDRef TemplateID, TMap<FGuid, FString>& InObjectBindingMap, bool bMatchByNameOnly, bool bCreateCameras)
{
if (bCreateCameras)
{
TArray<FbxCamera*> AllCameras;
MovieSceneToolHelpers::GetCameras(FbxImporter->Scene->GetRootNode(), AllCameras);
// Find unmatched cameras
TArray<FbxCamera*> UnmatchedCameras;
for (auto Camera : AllCameras)
{
FString NodeName = MovieSceneToolHelpers::GetCameraName(Camera);
bool bMatched = false;
for (auto InObjectBinding : InObjectBindingMap)
{
FString ObjectName = InObjectBinding.Value;
if (ObjectName == NodeName)
{
// Look for a valid bound object, otherwise need to create a new camera and assign this binding to it
bool bFoundBoundObject = false;
TArrayView<TWeakObjectPtr<>> BoundObjects = Player->FindBoundObjects(InObjectBinding.Key, TemplateID);
for (auto BoundObject : BoundObjects)
{
if (BoundObject.IsValid())
{
bFoundBoundObject = true;
break;
}
}
}
}
if (!bMatched)
{
UnmatchedCameras.Add(Camera);
}
}
// If there are new cameras, clear the object binding map so that we're only assigning values to the newly created cameras
if (UnmatchedCameras.Num() != 0)
{
InObjectBindingMap.Reset();
bMatchByNameOnly = true;
}
// Add any unmatched cameras
for (auto UnmatchedCamera : UnmatchedCameras)
{
FString CameraName = MovieSceneToolHelpers::GetCameraName(UnmatchedCamera);
AActor* NewCamera = nullptr;
if (UnmatchedCamera->GetApertureMode() == FbxCamera::eFocalLength)
{
FActorSpawnParameters SpawnParams;
NewCamera = World->SpawnActor<ACineCameraActor>(SpawnParams);
NewCamera->SetActorLabel(*CameraName);
}
else
{
FActorSpawnParameters SpawnParams;
NewCamera = World->SpawnActor<ACameraActor>(SpawnParams);
NewCamera->SetActorLabel(*CameraName);
}
// Copy camera properties before adding default tracks so that initial camera properties match and can be restored after sequencer finishes
MovieSceneToolHelpers::CopyCameraProperties(UnmatchedCamera, NewCamera);
TArray<TWeakObjectPtr<AActor> > NewCameras;
NewCameras.Add(NewCamera);
TArray<FGuid> NewCameraGuids = AddActors(World, Sequence,InMovieScene, Player, TemplateID,NewCameras);
if (NewCameraGuids.Num())
{
InObjectBindingMap.Add(NewCameraGuids[0]);
InObjectBindingMap[NewCameraGuids[0]] = CameraName;
}
}
}
//everything created now import it in.
MovieSceneToolHelpers::ImportFBXCameraToExisting(FbxImporter, Sequence, Player, TemplateID, InObjectBindingMap, bMatchByNameOnly, true);
}
bool ImportFBXInternal(UWorld* World, UMovieSceneSequence* Sequence, const TArray<FSequencerBindingProxy>& InBindings, UMovieSceneUserImportFBXSettings* ImportFBXSettings, const FString& ImportFilename, UMovieSceneSequencePlayer* Player)
{
UMovieScene* MovieScene = Sequence->GetMovieScene();
if (!MovieScene || MovieScene->IsReadOnly())
{
return false;
}
TArray<FSequencerBindingProxy> AllBindings;
for (const FSequencerBindingProxy& Binding : InBindings)
{
AllBindings.Add(Binding);
GatherDescendantBindings(Binding, Sequence, AllBindings);
}
TMap<FGuid, FString> ObjectBindingMap;
for (const FSequencerBindingProxy& Binding : AllBindings)
{
FString Name = MovieScene->GetObjectDisplayName(Binding.BindingID).ToString();
ObjectBindingMap.Add(Binding.BindingID, Name);
}
FFBXInOutParameters InOutParams;
if (!MovieSceneToolHelpers::ReadyFBXForImport(ImportFilename, ImportFBXSettings, InOutParams))
{
return false;
}
const bool bMatchByNameOnly = ImportFBXSettings->bMatchByNameOnly;
Player->State.AssignSequence(MovieSceneSequenceID::Root, *Sequence, *Player);
UnFbx::FFbxImporter* FbxImporter = UnFbx::FFbxImporter::GetInstance();
bool bResult = false;
FScopedTransaction ImportFBXTransaction(NSLOCTEXT("Sequencer", "ImportFBX", "Import FBX"));
{
FSpawnableRestoreState SpawnableRestoreState(MovieScene);
if (SpawnableRestoreState.bWasChanged)
{
// Evaluate at the beginning of the subscene time to ensure that spawnables are created before export
Player->SetPlaybackPosition(FMovieSceneSequencePlaybackParams(UE::MovieScene::DiscreteInclusiveLower(MovieScene->GetPlaybackRange()).Value, EUpdatePositionMethod::Play));
}
ImportFBXCamera(FbxImporter, World, Sequence, MovieScene, Player, MovieSceneSequenceID::Root, ObjectBindingMap, bMatchByNameOnly, ImportFBXSettings->bCreateCameras);
bResult = MovieSceneToolHelpers::ImportFBXIfReady(World, Sequence, Player, MovieSceneSequenceID::Root, ObjectBindingMap, ImportFBXSettings, InOutParams);
}
Player->Stop();
return bResult;
}
bool USequencerToolsFunctionLibrary::ImportLevelSequenceFBX(UWorld* World, ULevelSequence* Sequence, const TArray<FSequencerBindingProxy>& InBindings, UMovieSceneUserImportFBXSettings* ImportFBXSettings, const FString& ImportFilename)
{
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(World, Sequence, Settings, OutActor);
Player->Initialize(Sequence, World->GetLevel(0), Settings, CameraSettings);
bool bSuccess = ImportFBXInternal(World, Sequence, InBindings, ImportFBXSettings, ImportFilename, Player);
World->DestroyActor(OutActor);
return bSuccess;
}
bool USequencerToolsFunctionLibrary::ImportFBXToControlRig(UWorld* World, ULevelSequence* Sequence, const FString& ControlRigTrackName, const TArray<FString>& ControlRigNames,
UMovieSceneUserImportFBXControlRigSettings* ImportFBXControlRigSettings,
const FString& ImportFilename)
{
UMovieScene* MovieScene = Sequence->GetMovieScene();
if (!MovieScene || MovieScene->IsReadOnly())
{
return false;
}
bool bValid = false;
const TArray<FMovieSceneBinding>& Bindings = MovieScene->GetBindings();
for (const FMovieSceneBinding& Binding : Bindings)
{
if (Binding.GetName() == ControlRigTrackName)
{
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(World, Sequence, Settings, OutActor);
Player->Initialize(Sequence, World->GetLevel(0), Settings, CameraSettings);
Player->State.AssignSequence(MovieSceneSequenceID::Root, *Sequence, *Player);
const TArray<UMovieSceneTrack*>& Tracks = Binding.GetTracks();
TArray<FName> SelectedControls;
for (UMovieSceneTrack* Track : Tracks)
{
INodeAndChannelMappings* ChannelMapping = Cast<INodeAndChannelMappings>(Track);
if (ChannelMapping)
{
TArray<FFBXNodeAndChannels>* NodeAndChannels = ChannelMapping->GetNodeAndChannelMappings(nullptr);
//use passed in controls for selected, actually selected controls should almost be empty anyway since we just loaded/set everything up.
for (const FString& StringName : ControlRigNames)
{
FName Name(*StringName);
SelectedControls.Add(Name);
}
bValid = MovieSceneToolHelpers::ImportFBXIntoControlRigChannels(MovieScene,ImportFilename, ImportFBXControlRigSettings,
NodeAndChannels, SelectedControls, MovieScene->GetTickResolution());
if (NodeAndChannels)
{
delete NodeAndChannels;
}
}
}
return bValid;
}
}
return false;
}
FMovieSceneEvent USequencerToolsFunctionLibrary::CreateEvent(UMovieSceneSequence* InSequence, UMovieSceneEventSectionBase* InSection, const FSequencerQuickBindingResult& InEndpoint, const TArray<FString>& InPayload)
{
FMovieSceneEvent Event;
if (InEndpoint.EventEndpoint == nullptr)
{
FFrame::KismetExecutionMessage(TEXT("Invalid endpoint, event will not be initialized"), ELogVerbosity::Warning);
return Event;
}
UMovieScene* MovieScene = InSequence->GetMovieScene();
FGuid ObjectBindingID;
MovieScene->FindTrackBinding(*InSection->GetTypedOuter<UMovieSceneTrack>(), ObjectBindingID);
UClass* BoundObjectPinClass = nullptr;
if (FMovieScenePossessable* Possessable = MovieScene->FindPossessable(ObjectBindingID))
{
BoundObjectPinClass = const_cast<UClass*>(Possessable->GetPossessedObjectClass());
}
else if (FMovieSceneSpawnable* Spawnable = MovieScene->FindSpawnable(ObjectBindingID))
{
BoundObjectPinClass = Spawnable->GetObjectTemplate()->GetClass();
}
InSection->Modify();
FMovieSceneEventUtils::BindEventSectionToBlueprint(InSection, InEndpoint.EventEndpoint->GetBlueprint());
UEdGraphPin* BoundObjectPin = FMovieSceneEventUtils::FindBoundObjectPin(InEndpoint.EventEndpoint, BoundObjectPinClass);
FMovieSceneEventUtils::SetEndpoint(&Event, InSection, InEndpoint.EventEndpoint, BoundObjectPin);
if (InEndpoint.PayloadNames.Num() != InPayload.Num())
{
const FString Message = FString::Printf(TEXT("Wrong number of payload values, expecting %i got %i"), InEndpoint.PayloadNames.Num(), InPayload.Num());
FFrame::KismetExecutionMessage(*Message, ELogVerbosity::Warning);
return Event;
}
for (int32 Index = 0; Index < InEndpoint.PayloadNames.Num(); Index++)
{
const FName PayloadName = FName(InEndpoint.PayloadNames[Index]);
if (!Event.PayloadVariables.Contains(PayloadName))
{
Event.PayloadVariables.Add(PayloadName);
Event.PayloadVariables[PayloadName].Value = InPayload[Index];
}
}
return Event;
}
bool USequencerToolsFunctionLibrary::IsEventEndpointValid(const FSequencerQuickBindingResult& InEndpoint)
{
return InEndpoint.EventEndpoint != nullptr;
}
FSequencerQuickBindingResult USequencerToolsFunctionLibrary::CreateQuickBinding(UMovieSceneSequence* InSequence, UObject* InObject, const FString& InFunctionName, bool bCallInEditor)
{
FSequencerQuickBindingResult Result;
FMovieSceneSequenceEditor* SequenceEditor = FMovieSceneSequenceEditor::Find(InSequence);
if (!SequenceEditor)
{
return Result;
}
UBlueprint* Blueprint = SequenceEditor->GetOrCreateDirectorBlueprint(InSequence);
if (!Blueprint)
{
return Result;
}
UMovieScene* MovieScene = InSequence->GetMovieScene();
FMovieSceneEventEndpointParameters Params;
Params.SanitizedObjectName = InObject->GetName();
Params.SanitizedEventName = InFunctionName;
Params.BoundObjectPinClass = InObject->GetClass();
UFunction* Function = InObject->GetClass()->FindFunctionByName(FName(InFunctionName));
if (Function == nullptr)
{
const FString Message = FString::Printf(TEXT("Cannot find function %s in class %s"), *(InFunctionName), *(InObject->GetClass()->GetName()));
FFrame::KismetExecutionMessage(*Message, ELogVerbosity::Warning);
return Result;
}
UBlueprintFunctionNodeSpawner* BlueprintFunctionNodeSpawner = UBlueprintFunctionNodeSpawner::Create(Function);
FBlueprintActionMenuItem Action(BlueprintFunctionNodeSpawner);
UK2Node_CustomEvent* NewEventEndpoint = FMovieSceneEventUtils::CreateUserFacingEvent(Blueprint, Params);
NewEventEndpoint->bCallInEditor = bCallInEditor;
Result.EventEndpoint = NewEventEndpoint;
UEdGraphPin* ThenPin = NewEventEndpoint->FindPin(UEdGraphSchema_K2::PN_Then, EGPD_Output);
UEdGraphPin* BoundObjectPin = FMovieSceneEventUtils::FindBoundObjectPin(NewEventEndpoint, Params.BoundObjectPinClass);
FVector2D NodePosition(NewEventEndpoint->NodePosX + 400.f, NewEventEndpoint->NodePosY);
UEdGraphNode* NewNode = Action.PerformAction(NewEventEndpoint->GetGraph(), BoundObjectPin ? BoundObjectPin : ThenPin, NodePosition);
if (NewNode == nullptr)
{
const FString Message = FString::Printf(TEXT("Failed creating blueprint event node for function %s"), *InFunctionName);
FFrame::KismetExecutionMessage(*Message, ELogVerbosity::Warning);
return Result;
}
// Link execution pins
UEdGraphPin* ExecPin = NewNode->FindPin(UEdGraphSchema_K2::PN_Execute, EGPD_Input);
if (ensure(ThenPin && ExecPin))
{
ThenPin->MakeLinkTo(ExecPin);
}
// Link payload parameters' pins
UK2Node_EditablePinBase* EditableNode = Cast<UK2Node_EditablePinBase>(NewEventEndpoint);
if (EditableNode)
{
for (UEdGraphPin* PayloadPin : NewNode->Pins)
{
if (PayloadPin != BoundObjectPin && PayloadPin->Direction == EGPD_Input && PayloadPin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec && PayloadPin->LinkedTo.Num() == 0)
{
Result.PayloadNames.Add(PayloadPin->PinName.ToString());
UEdGraphPin* NewPin = EditableNode->CreateUserDefinedPin(PayloadPin->PinName, PayloadPin->PinType, EGPD_Output);
if (NewNode != NewEventEndpoint && NewPin)
{
NewPin->MakeLinkTo(PayloadPin);
}
}
}
}
return Result;
}
Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 4071915) #lockdown Nick.Penwarden #rb none ============================ MAJOR FEATURES & CHANGES ============================ Change 4060527 by Anousack.Kitisa Added support for importing FBX user properties as metadata on StaticMesh when importing FBX. Added support for exporting StaticMesh metadata as FBX user properties when exporting StaticMesh to FBX. #jira UESP-567 Change 4060835 by Jamie.Dale Added assign method to Python exposed structs This lets you assign the value of one struct instance onto another instance (rather than copy the pointer in Python). It also accepts anything that casts to the destination struct. Change 4060838 by Jamie.Dale Include unary operator function tooltips in doc string Change 4060843 by Jamie.Dale Fixed PythonizeValue including deprecated properties in the init function for a struct Change 4060908 by Jamie.Dale Fixed some name conflicts in generated Python glue Change 4061065 by Jamie.Dale Stubbed struct return values are now default constructed Change 4061205 by David.Hibbitts Added blueprint functions to create a message bus source, for use in projects where the Editor UI is not available or is impractical. Added a blueprint function to get available subject names for the LiveLink Client Added a RemoveSource method to ILiveLinkClient Added a GetSubjectNames method to ILiveLinkClient Fixed a crash when RequestShutdown was called on a MessageBusSource after the HeartbeatManager had already been shut down. Change 4061421 by Patrick.Boutot [AJA] Warn the user if he requested the key and the backbuffer is not setup properly. #jira UE-58614 Change 4061620 by Jamie.Dale Made the Sphinx config a template so we can inject the current engine version into it Change 4062578 by Jamie.Dale Optimized Python stub and doc gen file writes - Files are now only written when they've changed. - We now only remove files that are stale. - No requests to generate stub and doc files are queued before the first Tick. Change 4062634 by Jamie.Dale No longer export FDateTime defaults to struct __init__ as they can be non-deterministic Change 4064275 by Jamie.Dale Added callbacks for when Python is initialized and shutdown so that external modules can hook-in appropriately Change 4064613 by James.McNatton Change to initialization for FVirtualCameraWaypoint and FVirtualCameraSettingsPreset to remove non-deterministic constructors and a few resulting cleanup items Change 4064878 by Patrick.Boutot Add timecode provider plugin to capture from the Audio jack. Change 4064910 by Patrick.Boutot [AJA] Add AjaTimecodeProvider that provider the timecode from a SDI input source. Change 4067451 by Jamie.Dale Added command line options to enable all plugins, optionally excluding certain plugins Change 4067489 by Simon.Tourangeau Support for DX12 quad buffer stereo rendering Change 4068640 by Patrick.Boutot Add a state to CustomTimeStep. Show the state of the CustomTimeStep in "stat fps". Change 4069147 by Patrick.Boutot Move Mediasmith console to Engine. Renamed to TimecodeSynchronizer. Change 4071727 by Matt.Hoffman Initial pass at exposing Sequencer's Render to Movie functionality to Python. All settings that can be adjusted via the UI can be set from Python and renders can be invoked for both in-editor capture as well as new process capture. A basic API is provided which enables querying if a render in progress and canceling an in progress one. #jira UESP-541 [CL 4071957 by JeanMichel Dignard in Main branch]
2018-05-14 17:38:22 -04:00
#undef LOCTEXT_NAMESPACE // "SequencerTools"