Пример #1
0
void FSequencer::DeleteSection(class UMovieSceneSection* Section)
{
	UMovieScene* MovieScene = GetFocusedMovieScene();
	
	bool bAnythingRemoved = false;

	UMovieSceneTrack* Track = CastChecked<UMovieSceneTrack>( Section->GetOuter() );

	// If this check fails then the section is outered to a type that doesnt know about the section
	//checkSlow( Track->HasSection(Section) );
	
	Track->SetFlags( RF_Transactional );

	FScopedTransaction DeleteSectionTransaction( NSLOCTEXT("Sequencer", "DeleteSection_Transaction", "Delete Section") );
	
	Track->Modify();

	Track->RemoveSection(Section);

	bAnythingRemoved = true;
	
	if( bAnythingRemoved )
	{
		UpdateRuntimeInstances();
	}
}
Пример #2
0
UMovieSceneTrack* UMovieScene::FindTrack( TSubclassOf<UMovieSceneTrack> TrackClass, const FGuid& ObjectGuid, FName UniqueTrackName ) const
{
	UMovieSceneTrack* FoundTrack = NULL;
	check( UniqueTrackName != NAME_None && ObjectGuid.IsValid() )

	for( int32 ObjectBindingIndex = 0; ObjectBindingIndex < ObjectBindings.Num(); ++ObjectBindingIndex )
	{
		const FMovieSceneObjectBinding& ObjectBinding = ObjectBindings[ObjectBindingIndex];

		if( ObjectBinding.GetObjectGuid() == ObjectGuid ) 
		{
			const TArray<UMovieSceneTrack*>& Tracks = ObjectBinding.GetTracks();
			for( int32 TrackIndex = 0; TrackIndex < Tracks.Num(); ++TrackIndex )
			{
				UMovieSceneTrack* Track = Tracks[TrackIndex];
				if( Track->GetClass() == TrackClass && Track->GetTrackName() == UniqueTrackName )
				{
					FoundTrack = Track;
					break;
				}
			}
		}
	}
	
	return FoundTrack;
}
UMovieSceneSection* UMovieSceneSection::SplitSection(float SplitTime)
{
	if (!IsTimeWithinSection(SplitTime))
	{
		return nullptr;
	}

	SetFlags(RF_Transactional);

	if (TryModify())
	{
		float SectionEndTime = GetEndTime();
				
		// Trim off the right
		SetEndTime(SplitTime);

		// Create a new section
		UMovieSceneTrack* Track = CastChecked<UMovieSceneTrack>(GetOuter());
		Track->Modify();

		UMovieSceneSection* NewSection = DuplicateObject<UMovieSceneSection>(this, Track);
		check(NewSection);

		NewSection->SetStartTime(SplitTime);
		NewSection->SetEndTime(SectionEndTime);
		Track->AddSection(*NewSection);

		return NewSection;
	}

	return nullptr;
}
void FSequencerDragOperation::GetSectionSnapTimes(TArray<float>& OutSnapTimes, UMovieSceneSection* Section, TSharedPtr<FTrackNode> SequencerNode, bool bIgnoreOurSectionCustomSnaps)
{
	// @todo Sequencer handle dilation snapping better

	// Collect all the potential snap times from other section borders
	const TArray< TSharedRef<ISequencerSection> >& Sections = SequencerNode->GetSections();
	for (int32 SectionIndex = 0; SectionIndex < Sections.Num(); ++SectionIndex)
	{
		const UMovieSceneSection* InSection = Sections[SectionIndex]->GetSectionObject();
		bool bIsThisSection = Section == InSection;
		if (!bIgnoreOurSectionCustomSnaps || !bIsThisSection)
		{
			InSection->GetSnapTimes(OutSnapTimes, Section != InSection);
		}
	}

	// snap to director track if it exists, and we are not the director track
	UMovieSceneTrack* OuterTrack = Cast<UMovieSceneTrack>(Section->GetOuter());
	UMovieScene* MovieScene = Cast<UMovieScene>(OuterTrack->GetOuter());
	UMovieSceneTrack* ShotTrack = MovieScene->FindMasterTrack(UMovieSceneShotTrack::StaticClass());
	if (ShotTrack && OuterTrack != ShotTrack)
	{
		const TArray<UMovieSceneSection*>& ShotSections = ShotTrack->GetAllSections();
		for (int32 SectionIndex = 0; SectionIndex < ShotSections.Num(); ++SectionIndex)
		{
			auto Shot = ShotSections[SectionIndex];
			Shot->GetSnapTimes(OutSnapTimes, true);
		}
	}
}
void FSlomoTrackEditor::HandleAddSlomoTrackMenuEntryExecute()
{
	UMovieScene* MovieScene = GetFocusedMovieScene();

	if (MovieScene == nullptr)
	{
		return;
	}

	UMovieSceneTrack* SlomoTrack = MovieScene->FindMasterTrack<UMovieSceneSlomoTrack>();

	if (SlomoTrack != nullptr)
	{
		return;
	}

	const FScopedTransaction Transaction(NSLOCTEXT("Sequencer", "AddSlomoTrack_Transaction", "Add Play Rate Track"));

	MovieScene->Modify();
		
	SlomoTrack = FindOrCreateMasterTrack<UMovieSceneSlomoTrack>().Track;
	ensure(SlomoTrack);

	UMovieSceneSection* NewSection = SlomoTrack->CreateNewSection();
	ensure(NewSection);

	SlomoTrack->AddSection(*NewSection);

	GetSequencer()->NotifyMovieSceneDataChanged();
}
bool F3DAttachTrackEditor::AddKeyInternal( float KeyTime, const TArray<TWeakObjectPtr<UObject>> Objects, const FName SocketName, const FName ComponentName, AActor* ParentActor)
{
	bool bHandleCreated = false;
	bool bTrackCreated = false;
	bool bTrackModified = false;

	FGuid ParentActorId;

	if (ParentActor != nullptr)
	{
		FFindOrCreateHandleResult HandleResult = FindOrCreateHandleToObject(ParentActor);
		ParentActorId = HandleResult.Handle;
		bHandleCreated |= HandleResult.bWasCreated;
	}

	if (!ParentActorId.IsValid())
	{
		return false;
	}

	for( int32 ObjectIndex = 0; ObjectIndex < Objects.Num(); ++ObjectIndex )
	{
		UObject* Object = Objects[ObjectIndex].Get();

		FFindOrCreateHandleResult HandleResult = FindOrCreateHandleToObject( Object );
		FGuid ObjectHandle = HandleResult.Handle;
		bHandleCreated |= HandleResult.bWasCreated;
		if (ObjectHandle.IsValid())
		{
			FFindOrCreateTrackResult TrackResult = FindOrCreateTrackForObject( ObjectHandle, UMovieScene3DAttachTrack::StaticClass());
			UMovieSceneTrack* Track = TrackResult.Track;
			bTrackCreated |= TrackResult.bWasCreated;

			if (ensure(Track))
			{
				// Clamp to next attach section's start time or the end of the current sequencer view range
				float AttachEndTime = GetSequencer()->GetViewRange().GetUpperBoundValue();

				for (int32 AttachSectionIndex = 0; AttachSectionIndex < Track->GetAllSections().Num(); ++AttachSectionIndex)
				{
					float StartTime = Track->GetAllSections()[AttachSectionIndex]->GetStartTime();
					float EndTime = Track->GetAllSections()[AttachSectionIndex]->GetEndTime();
					if (KeyTime < StartTime)
					{
						if (AttachEndTime > StartTime)
						{
							AttachEndTime = StartTime;
						}
					}
				}

				Cast<UMovieScene3DAttachTrack>(Track)->AddConstraint( KeyTime, AttachEndTime, SocketName, ComponentName, ParentActorId );
				bTrackModified = true;
			}
		}
	}

	return bHandleCreated || bTrackCreated || bTrackModified;
}
void FMovieSceneSequenceInstance::RefreshInstanceMap( const TArray<UMovieSceneTrack*>& Tracks, const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, FMovieSceneInstanceMap& TrackInstances, IMovieScenePlayer& Player  )
{
	// All the tracks we found during this pass
	TSet< UMovieSceneTrack* > FoundTracks;

	// For every track, check if it has an instance, if not create one, otherwise refresh that instance
	for( int32 TrackIndex = 0; TrackIndex < Tracks.Num(); ++TrackIndex )
	{
		UMovieSceneTrack* Track = Tracks[TrackIndex];

		// A new track has been encountered
		FoundTracks.Add( Track );

		// See if the track has an instance
		TSharedPtr<IMovieSceneTrackInstance> Instance = TrackInstances.FindRef( Track );
		if ( !Instance.IsValid() )
		{
			// The track does not have an instance, create one
			Instance = Track->CreateInstance();
			Instance->RefreshInstance( RuntimeObjects, Player, *this );
			Instance->SaveState(RuntimeObjects, Player, *this);

			TrackInstances.Add( Track, Instance );
		}
		else
		{
			// The track has an instance, refresh it
			Instance->RefreshInstance( RuntimeObjects, Player, *this );
			Instance->SaveState(RuntimeObjects, Player, *this);
		}

	}

	// Remove entries which no longer have a track associated with them
	FMovieSceneInstanceMap::TIterator It = TrackInstances.CreateIterator();
	for( ; It; ++It )
	{
		if( !FoundTracks.Contains( It.Key().Get() ) )
		{
			It.Value()->ClearInstance( Player, *this );

			// This track was not found in the moviescene's track list so it was removed.
			It.RemoveCurrent();
		}
	}

	// Sort based on evaluation order
	TrackInstances.ValueSort(FTrackInstanceEvalSorter());
}
Пример #8
0
UMovieSceneTrack* UMovieScene::FindMasterTrack( TSubclassOf<UMovieSceneTrack> TrackClass ) const
{
	UMovieSceneTrack* FoundTrack = NULL;
	for( int32 TrackIndex = 0; TrackIndex < MasterTracks.Num(); ++TrackIndex )
	{
		UMovieSceneTrack* Track = MasterTracks[TrackIndex];
		if( Track->GetClass() == TrackClass )
		{
			FoundTrack = Track;
			break;
		}
	}

	return FoundTrack;
}
TSharedRef<ISequencerSection> F2DTransformTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track )
{
	check( SupportsType( SectionObject.GetOuter()->GetClass() ) );

	UClass* SectionClass = SectionObject.GetOuter()->GetClass();
	return MakeShareable( new F2DTransformSection( SectionObject, Track.GetTrackName() ) );
}
UMovieSceneSubSection* UMovieSceneSubSection::GetRecordingSection()
{
	// check if the section is still valid and part of a track (i.e. it has not been deleted or GCed)
	if(TheRecordingSection.IsValid())
	{
		UMovieSceneTrack* TrackOuter = Cast<UMovieSceneTrack>(TheRecordingSection->GetOuter());
		if(TrackOuter)
		{
			if(TrackOuter->HasSection(*TheRecordingSection.Get()))
			{
				return TheRecordingSection.Get();
			}
		}
	}

	return nullptr;
}
void FMoveSection::OnEndDrag(TSharedPtr<FTrackNode> SequencerNode)
{
	DraggedKeyHandles.Empty();

	if (Section.IsValid())
	{
		SequencerNode->FixRowIndices();

		UMovieSceneTrack* OuterTrack = Cast<UMovieSceneTrack>(Section->GetOuter());

		if (OuterTrack)
		{
			OuterTrack->Modify();
			OuterTrack->OnSectionMoved(*Section);
		}
	}

	EndTransaction();
}
Пример #12
0
void FSequencerNodeTree::MakeSectionInterfaces( UMovieSceneTrack& Track, TSharedRef<FTrackNode>& SectionAreaNode )
{
	const TArray<UMovieSceneSection*>& MovieSceneSections = Track.GetAllSections();

	TSharedRef<FMovieSceneTrackEditor> Editor = FindOrAddTypeEditor( Track );

	for (int32 SectionIndex = 0; SectionIndex < MovieSceneSections.Num(); ++SectionIndex )
	{
		UMovieSceneSection* SectionObject = MovieSceneSections[SectionIndex];
		TSharedRef<ISequencerSection> Section = Editor->MakeSectionInterface( *SectionObject, &Track );

		// Ask the section to generate it's inner layout
		FSectionLayoutBuilder Builder( SectionAreaNode );
		Section->GenerateSectionLayout( Builder );

		SectionAreaNode->AddSection( Section );
	}

	SectionAreaNode->FixRowIndices();
}
Пример #13
0
TSharedRef<FMovieSceneTrackEditor> FSequencerNodeTree::FindOrAddTypeEditor( UMovieSceneTrack& InTrack )
{
	TSharedPtr<FMovieSceneTrackEditor> Editor = EditorMap.FindRef( &InTrack );

	if( !Editor.IsValid() )
	{
		const TArray< TSharedPtr<FMovieSceneTrackEditor> >& TrackEditors = Sequencer.GetTrackEditors();

		// Get a tool for each track
		// @todo Sequencer - Should probably only need to get this once and it shouldnt be done here. It depends on when movie scene tool modules are loaded
		TSharedPtr<FMovieSceneTrackEditor> SupportedTool;
		for( int32 EditorIndex = 0; EditorIndex < TrackEditors.Num(); ++EditorIndex )
		{
			if( TrackEditors[EditorIndex]->SupportsType( InTrack.GetClass() ) )
			{
				Editor = TrackEditors[EditorIndex];
				EditorMap.Add( &InTrack, Editor );
				break;
			}
		}
	}

	return Editor.ToSharedRef();
}
TSharedRef<ISequencerSection> FColorPropertyTrackEditor::MakeSectionInterface(UMovieSceneSection& SectionObject, UMovieSceneTrack& Track, FGuid ObjectBinding)
{
	UMovieScenePropertyTrack* PropertyTrack = Cast<UMovieScenePropertyTrack>(&Track);
	checkf(PropertyTrack != nullptr, TEXT("Incompatible track in FColorPropertyTrackEditor"));
	return MakeShareable(new FColorPropertySection(GetSequencer().Get(), ObjectBinding, PropertyTrack->GetPropertyName(), PropertyTrack->GetPropertyPath(), SectionObject, Track.GetDisplayName()));
}
Пример #15
0
TSharedRef<ISequencerSection> FSubMovieSceneTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track )
{
	return MakeShareable( new FSubMovieSceneSection( GetSequencer(), SectionObject, Track.GetTrackName() ) );
}
Пример #16
0
TSharedRef<ISequencerSection> FBytePropertyTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track )
{
	return MakeShareable( new FBytePropertySection( SectionObject, Track.GetTrackName(), Cast<UMovieSceneByteTrack>( SectionObject.GetOuter() )->GetEnum() ) );
}
Пример #17
0
void FSequencerNodeTree::Update()
{
	// @todo Sequencer - This update pass is too aggressive.  Some nodes may still be valid
	Empty();

	UMovieScene* MovieScene = Sequencer.GetFocusedMovieSceneSequence()->GetMovieScene();

	TArray< TSharedRef<FSequencerDisplayNode> > NewRootNodes;

	// Get the master tracks  so we can get sections from them
	const TArray<UMovieSceneTrack*>& MasterTracks = MovieScene->GetMasterTracks();

	for( UMovieSceneTrack* Track : MasterTracks )
	{
		UMovieSceneTrack& TrackRef = *Track;

		TSharedRef<FTrackNode> SectionNode = MakeShareable( new FTrackNode( TrackRef.GetTrackName(), TrackRef, NULL, *this ) );
		NewRootNodes.Add( SectionNode );
	
		MakeSectionInterfaces( TrackRef, SectionNode );

		SectionNode->PinNode();
	}


	const TArray<FMovieSceneBinding>& Bindings = MovieScene->GetBindings();

	TMap<FGuid, const FMovieSceneBinding*> GuidToBindingMap;
	for (const FMovieSceneBinding& Binding : Bindings)
	{
		GuidToBindingMap.Add(Binding.GetObjectGuid(), &Binding);
	}

	// Make nodes for all object bindings
	TArray< TSharedRef<FSequencerDisplayNode> > NewObjectNodes;
	for( const FMovieSceneBinding& Binding : Bindings )
	{
		TSharedRef<FObjectBindingNode> ObjectBindingNode = AddObjectBinding( Binding.GetName(), Binding.GetObjectGuid(), GuidToBindingMap, NewObjectNodes );

		const TArray<UMovieSceneTrack*>& Tracks = Binding.GetTracks();

		for( UMovieSceneTrack* Track : Tracks )
		{
			UMovieSceneTrack& TrackRef = *Track;

			FName SectionName = TrackRef.GetTrackName();
			check( SectionName != NAME_None );

			TSharedRef<FTrackNode> SectionAreaNode = ObjectBindingNode->AddSectionAreaNode( SectionName, TrackRef );
			MakeSectionInterfaces( TrackRef, SectionAreaNode );
		}
	}

	struct FObjectNodeSorter
	{
		bool operator()( const TSharedRef<FSequencerDisplayNode>& A, const TSharedRef<FSequencerDisplayNode>& B ) const
		{
			if (A->GetType() == ESequencerNode::Object && B->GetType() != ESequencerNode::Object)
			{
				return true;
			}
			if (A->GetType() != ESequencerNode::Object && B->GetType() == ESequencerNode::Object)
			{
				return false;
			}
			return A->GetDisplayName().ToString() < B->GetDisplayName().ToString();
		}
	};

	NewObjectNodes.Sort( FObjectNodeSorter() );
	for (TSharedRef<FSequencerDisplayNode> NewObjectNode : NewObjectNodes)
	{
		NewObjectNode->SortChildNodes(FObjectNodeSorter());
	}

	NewRootNodes.Append(NewObjectNodes);

	// Look for a shot track.  It will always come first if it exists
	UMovieSceneTrack* ShotTrack = MovieScene->GetShotTrack();
	if( ShotTrack )
	{
		TSharedRef<FTrackNode> SectionNode = MakeShareable( new FTrackNode( ShotTrack->GetTrackName(), *ShotTrack, NULL, *this ) );

		// Shot track always comes first
		RootNodes.Add( SectionNode );

		MakeSectionInterfaces( *ShotTrack, SectionNode );

		SectionNode->PinNode();
	}

	// Add all other nodes after the shot track
	RootNodes.Append( NewRootNodes );

	// Set up virtual offsets, and expansion states
	float VerticalOffset = 0.f;
	for (auto& Node : RootNodes)
	{
		Node->Traverse_ParentFirst([&](FSequencerDisplayNode& InNode){

			float VerticalTop = VerticalOffset;
			VerticalOffset += InNode.GetNodeHeight() + InNode.GetNodePadding().Combined();
			InNode.Initialize(VerticalTop, VerticalOffset);
			return true;
		});

	}

	// Re-filter the tree after updating 
	// @todo Sequencer - Newly added sections may need to be visible even when there is a filter
	FilterNodes( FilterString );
}
FMovieSceneSequenceInstance::FMovieSceneSequenceInstance(const UMovieSceneTrack& InMovieSceneTrack)
{
	TimeRange = CastChecked<UMovieScene>(InMovieSceneTrack.GetOuter())->GetPlaybackRange();
}
TSharedRef<FPropertySection> FBoolPropertyTrackEditor::MakePropertySectionInterface(UMovieSceneSection& SectionObject, UMovieSceneTrack& Track)
{
	return MakeShareable(new FBoolPropertySection(SectionObject, Track.GetDisplayName(), GetSequencer().Get()));
}
FSequencerTrackNode::FSequencerTrackNode(UMovieSceneTrack& InAssociatedTrack, ISequencerTrackEditor& InAssociatedEditor, bool bInCanBeDragged, TSharedPtr<FSequencerDisplayNode> InParentNode, FSequencerNodeTree& InParentTree)
	: FSequencerDisplayNode(InAssociatedTrack.GetTrackName(), InParentNode, InParentTree)
	, AssociatedEditor(InAssociatedEditor)
	, AssociatedTrack(&InAssociatedTrack)
	, bCanBeDragged(bInCanBeDragged)
{ }