コード例 #1
0
TSharedRef<FObjectBindingNode> FSequencerNodeTree::AddObjectBinding(const FString& ObjectName, const FGuid& ObjectBinding, TMap<FGuid, const FMovieSceneBinding*>& GuidToBindingMap, TArray< TSharedRef<FSequencerDisplayNode> >& OutNodeList)
{
	TSharedPtr<FObjectBindingNode> ObjectNode;
	TSharedPtr<FObjectBindingNode>* FoundObjectNode = ObjectBindingMap.Find(ObjectBinding);
	if (FoundObjectNode != nullptr)
	{
		ObjectNode = *FoundObjectNode;
	}
	else
	{
		// The node name is the object guid
		FName ObjectNodeName = *ObjectBinding.ToString();

		// Try to get the parent object node if there is one.
		TSharedPtr<FObjectBindingNode> ParentNode;
		TArray<UObject*> RuntimeObjects;
		UMovieSceneSequence* Animation = Sequencer.GetFocusedMovieSceneSequence();
		UObject* RuntimeObject = Animation->FindObject(ObjectBinding);
		if ( RuntimeObject != nullptr)
		{
			UObject* ParentObject = Animation->GetParentObject(RuntimeObject);
			if (ParentObject != nullptr)
			{
				FGuid ParentBinding = Animation->FindObjectId(*ParentObject);
				TSharedPtr<FObjectBindingNode>* FoundParentNode = ObjectBindingMap.Find( ParentBinding );
				if ( FoundParentNode != nullptr )
				{
					ParentNode = *FoundParentNode;
				}
				else
				{
					const FMovieSceneBinding** FoundParentMovieSceneBinding = GuidToBindingMap.Find( ParentBinding );
					if ( FoundParentMovieSceneBinding != nullptr )
					{
						ParentNode = AddObjectBinding( (*FoundParentMovieSceneBinding)->GetName(), ParentBinding, GuidToBindingMap, OutNodeList );
					}
				}
			}
		}

		// Create the node.
		ObjectNode = MakeShareable( new FObjectBindingNode( ObjectNodeName, ObjectName, ObjectBinding, ParentNode, *this ) );
		if (ParentNode.IsValid())
		{
			ParentNode->AddObjectBindingNode(ObjectNode.ToSharedRef());
		}
		else
		{
			OutNodeList.Add( ObjectNode.ToSharedRef() );
		}

		// Map the guid to the object binding node for fast lookup later
		ObjectBindingMap.Add( ObjectBinding, ObjectNode );
	}

	return ObjectNode.ToSharedRef();
}
コード例 #2
0
void FColorPropertySection::ConsolidateColorCurves( TArray< TKeyValuePair<float, FLinearColor> >& OutColorKeys, const UMovieSceneColorSection* Section ) const
{
	// Get the default color of the first instance
	FLinearColor DefaultColor( 0.0f, 0.0f, 0.0f, 0.0f );

	static const FName SlateColorName( "SlateColor" );

	UMovieSceneSequence* Sequence = Sequencer->GetFocusedMovieSceneSequence();

	const TArray<FMovieSceneBinding>& MovieSceneBindings = Sequence->GetMovieScene()->GetBindings();

	bool bFoundColor = false;
	for ( int32 BindingIndex = 0; BindingIndex < MovieSceneBindings.Num() && !bFoundColor; ++BindingIndex )
	{
		const FMovieSceneBinding& MovieSceneBinding = MovieSceneBindings[BindingIndex];

		for ( int32 TrackIndex = 0; TrackIndex < MovieSceneBinding.GetTracks().Num() && !bFoundColor; ++TrackIndex )
		{
			if ( MovieSceneBinding.GetTracks()[TrackIndex] == Track )
			{
				UObject* RuntimeObject = Sequence->FindObject( MovieSceneBinding.GetObjectGuid() );

				if ( RuntimeObject != nullptr )
				{
					UProperty* Property = RuntimeObject->GetClass()->FindPropertyByName( CastChecked<UMovieSceneColorTrack>( Track )->GetPropertyName() );
					UStructProperty* ColorStructProp = Cast<UStructProperty>( Property );
					if ( ColorStructProp && ColorStructProp->Struct )
					{
						if ( ColorStructProp->Struct->GetFName() == SlateColorName )
						{
							DefaultColor = (*Property->ContainerPtrToValuePtr<FSlateColor>( RuntimeObject )).GetSpecifiedColor();
						}
						else if ( ColorStructProp->Struct->GetFName() == NAME_LinearColor )
						{
							DefaultColor = *Property->ContainerPtrToValuePtr<FLinearColor>( RuntimeObject );
						}
						else
						{
							DefaultColor = Property->ContainerPtrToValuePtr<FColor>( RuntimeObject )->ReinterpretAsLinear();
						}
						bFoundColor = true;
						break;
					}
				}
			}
		}
	}

	// @todo Sequencer Optimize - This could all get cached, instead of recalculating everything every OnPaint

	const FRichCurve* Curves[4] = {
		&Section->GetRedCurve(),
		&Section->GetGreenCurve(),
		&Section->GetBlueCurve(),
		&Section->GetAlphaCurve()
	};

	// @todo Sequencer Optimize - This is a O(n^2) loop!
	// Our times are floats, which means we can't use a map and
	// do a quick lookup to see if the keys already exist
	// because the keys are ordered, we could take advantage of that, however
	TArray<float> TimesWithKeys;
	for ( int32 i = 0; i < 4; ++i )
	{
		const FRichCurve* Curve = Curves[i];
		for ( auto It( Curve->GetKeyIterator() ); It; ++It )
		{
			float KeyTime = It->Time;

			bool bShouldAddKey = true;

			int32 InsertKeyIndex = INDEX_NONE;
			for ( int32 k = 0; k < TimesWithKeys.Num(); ++k )
			{
				if ( FMath::IsNearlyEqual( TimesWithKeys[k], KeyTime ) )
				{
					bShouldAddKey = false;
					break;
				}
				else if ( TimesWithKeys[k] > KeyTime )
				{
					InsertKeyIndex = k;
					break;
				}
			}

			if ( InsertKeyIndex == INDEX_NONE && bShouldAddKey )
			{
				InsertKeyIndex = TimesWithKeys.Num();
			}

			if ( bShouldAddKey )
			{
				TimesWithKeys.Insert( KeyTime, InsertKeyIndex );
			}
		}
	}

	// @todo Sequencer Optimize - This another O(n^2) loop, since Eval is O(n)!
	for ( int32 i = 0; i < TimesWithKeys.Num(); ++i )
	{
		OutColorKeys.Add( TKeyValuePair<float, FLinearColor>( TimesWithKeys[i], Section->Eval( TimesWithKeys[i], DefaultColor ) ) );
	}
}