FVector2D FParticleSection::GetKeyBrushOrigin( FKeyHandle KeyHandle ) const { UMovieSceneParticleSection* ParticleSection = Cast<UMovieSceneParticleSection>( &Section ); if ( ParticleSection != nullptr ) { FIntegralKey ParticleKey = ParticleSection->GetParticleCurve().GetKey(KeyHandle); if ( (EParticleKey::Type)ParticleKey.Value == EParticleKey::Activate ) { return FVector2D(-1.0f, 1.0f); } else if ( (EParticleKey::Type)ParticleKey.Value == EParticleKey::Deactivate ) { return FVector2D(1.0f, 1.0f); } } return FVector2D(0.0f, 0.0f); }
const FSlateBrush* FParticleSection::GetKeyBrush( FKeyHandle KeyHandle ) const { UMovieSceneParticleSection* ParticleSection = Cast<UMovieSceneParticleSection>( &Section ); if ( ParticleSection != nullptr ) { FIntegralKey ParticleKey = ParticleSection->GetParticleCurve().GetKey(KeyHandle); if ( (EParticleKey::Type)ParticleKey.Value == EParticleKey::Activate ) { return LeftKeyBrush; } else if ( (EParticleKey::Type)ParticleKey.Value == EParticleKey::Deactivate ) { return RightKeyBrush; } } return nullptr; }
void FMatineeImportTools::CopyInterpParticleTrack( TSharedRef<ISequencer> Sequencer, UInterpTrackToggle* MatineeToggleTrack, UMovieSceneParticleTrack* ParticleTrack ) { const FScopedTransaction Transaction( NSLOCTEXT( "Sequencer", "PasteMatineeParticleTrack", "Paste Matinee particle track" ) ); bool bSectionCreated = false; ParticleTrack->Modify(); float KeyTime = MatineeToggleTrack->GetKeyframeTime( 0 ); UMovieSceneParticleSection* Section = Cast<UMovieSceneParticleSection>( MovieSceneHelpers::FindSectionAtTime( ParticleTrack->GetAllSections(), KeyTime ) ); if ( Section == nullptr ) { Section = Cast<UMovieSceneParticleSection>( ParticleTrack->CreateNewSection() ); ParticleTrack->AddSection( *Section ); bSectionCreated = true; } if (Section->TryModify()) { float SectionMin = Section->GetStartTime(); float SectionMax = Section->GetEndTime(); FIntegralCurve& ParticleCurve = Section->GetParticleCurve(); for ( const auto& Key : MatineeToggleTrack->ToggleTrack ) { EParticleKey::Type ParticleKey; if ( TryConvertMatineeToggleToOutParticleKey( Key.ToggleAction, ParticleKey ) ) { ParticleCurve.AddKey( Key.Time, (int32)ParticleKey, ParticleCurve.FindKey( Key.Time ) ); } SectionMin = FMath::Min( SectionMin, Key.Time ); SectionMax = FMath::Max( SectionMax, Key.Time ); } Section->SetStartTime( SectionMin ); Section->SetEndTime( SectionMax ); if ( bSectionCreated ) { Sequencer->NotifyMovieSceneDataChanged(); } } }
int32 FParticleSection::OnPaintSection( FSequencerSectionPainter& InPainter ) const { TSharedPtr<ISequencer> OwningSequencer = OwningSequencerPtr.Pin(); if (!OwningSequencer.IsValid()) { return InPainter.LayerId + 1; } const ESlateDrawEffect::Type DrawEffects = InPainter.bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; UMovieSceneParticleSection* AnimSection = Cast<UMovieSceneParticleSection>( &Section ); const FTimeToPixel& TimeToPixelConverter = InPainter.GetTimeConverter(); FLinearColor TrackColor; // @todo Sequencer - These values should be cached and then refreshed only when the particle system changes. bool bIsLooping = false; float LastEmitterEndTime = 0; UMovieSceneParticleSection* ParticleSection = Cast<UMovieSceneParticleSection>( &Section ); if ( ParticleSection != nullptr ) { UMovieSceneParticleTrack* ParentTrack = Cast<UMovieSceneParticleTrack>( ParticleSection->GetOuter() ); if ( ParentTrack != nullptr ) { TrackColor = ParentTrack->GetColorTint(); FGuid ObjectHandle; for ( const FMovieSceneBinding& Binding : OwningSequencer->GetFocusedMovieSceneSequence()->GetMovieScene()->GetBindings() ) { if ( Binding.GetTracks().Contains( ParentTrack ) ) { ObjectHandle = Binding.GetObjectGuid(); break; } } if ( ObjectHandle.IsValid() ) { UObject* BoundObject = OwningSequencer->GetFocusedMovieSceneSequenceInstance()->FindObject( ObjectHandle, *OwningSequencer ); UParticleSystemComponent* ParticleSystemComponent = Cast<UParticleSystemComponent>(BoundObject); if(AEmitter* ParticleSystemActor = Cast<AEmitter>(BoundObject)) { ParticleSystemComponent = ParticleSystemActor->GetParticleSystemComponent(); } if ( ParticleSystemComponent != nullptr && ParticleSystemComponent->Template != nullptr ) { for ( UParticleEmitter* Emitter : ParticleSystemComponent->Template->Emitters ) { UParticleModuleRequired* RequiredModule = Emitter->GetLODLevel( 0 )->RequiredModule; bIsLooping |= RequiredModule->EmitterLoops == 0; LastEmitterEndTime = FMath::Max( LastEmitterEndTime, RequiredModule->EmitterDelay + RequiredModule->EmitterDuration ); } } } } } // @todo Sequencer - This should only draw the visible ranges. TArray<TRange<float>> DrawRanges; TOptional<float> CurrentRangeStart; for ( auto KeyIterator = ParticleSection->GetParticleCurve().GetKeyIterator(); KeyIterator; ++KeyIterator ) { FIntegralKey Key = *KeyIterator; if ( (EParticleKey::Type)Key.Value == EParticleKey::Activate ) { if ( CurrentRangeStart.IsSet() == false ) { CurrentRangeStart = Key.Time; } else { if ( bIsLooping == false ) { if ( Key.Time > CurrentRangeStart.GetValue() + LastEmitterEndTime ) { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), CurrentRangeStart.GetValue() + LastEmitterEndTime ) ); } else { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), Key.Time ) ); } CurrentRangeStart = Key.Time; } } } if ( (EParticleKey::Type)Key.Value == EParticleKey::Deactivate ) { if ( CurrentRangeStart.IsSet() ) { if (bIsLooping) { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), Key.Time ) ); } else { if ( Key.Time > CurrentRangeStart.GetValue() + LastEmitterEndTime ) { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), CurrentRangeStart.GetValue() + LastEmitterEndTime ) ); } else { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), Key.Time ) ); } } CurrentRangeStart.Reset(); } } } if ( CurrentRangeStart.IsSet() ) { if ( bIsLooping ) { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), OwningSequencer->GetViewRange().GetUpperBoundValue() ) ); } else { DrawRanges.Add( TRange<float>( CurrentRangeStart.GetValue(), CurrentRangeStart.GetValue() + LastEmitterEndTime ) ); } } for ( const TRange<float>& DrawRange : DrawRanges ) { float XOffset = TimeToPixelConverter.TimeToPixel(DrawRange.GetLowerBoundValue()); float XSize = TimeToPixelConverter.TimeToPixel(DrawRange.GetUpperBoundValue()) - XOffset; FSlateDrawElement::MakeBox( InPainter.DrawElements, InPainter.LayerId, InPainter.SectionGeometry.ToPaintGeometry( FVector2D( XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2 ), FVector2D( XSize, SequencerSectionConstants::KeySize.Y ) ), FEditorStyle::GetBrush( "Sequencer.Section.Background" ), InPainter.SectionClippingRect, DrawEffects ); FSlateDrawElement::MakeBox( InPainter.DrawElements, InPainter.LayerId, InPainter.SectionGeometry.ToPaintGeometry( FVector2D( XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2 ), FVector2D( XSize, SequencerSectionConstants::KeySize.Y ) ), FEditorStyle::GetBrush( "Sequencer.Section.BackgroundTint" ), InPainter.SectionClippingRect, DrawEffects, TrackColor ); } return InPainter.LayerId+1; }
void FParticleSection::GenerateSectionLayout( class ISectionLayoutBuilder& LayoutBuilder ) const { UMovieSceneParticleSection* ParticleSection = Cast<UMovieSceneParticleSection>( &Section ); LayoutBuilder.SetSectionAsKeyArea( MakeShareable( new FEnumKeyArea( ParticleSection->GetParticleCurve(), ParticleSection, ParticleKeyEnum ) ) ); }