/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Operations on selected actors. // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TArray< TWeakObjectPtr< AActor > > FLayers::GetSelectedActors() const { // Unfortunately, the batch selection operation is not entirely effective // and the result can be that the iterator becomes invalid when adding an actor to a layer // due to unintended selection change notifications being fired. TArray< TWeakObjectPtr< AActor > > CurrentlySelectedActors; for( FSelectionIterator It( Editor->GetSelectedActorIterator() ); It; ++It ) { const TWeakObjectPtr< AActor > Actor = static_cast< AActor* >( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); CurrentlySelectedActors.Add( Actor ); } return CurrentlySelectedActors; }
void FPropertyTableColumn::GenerateColumnDisplayName() { TWeakObjectPtr< UObject > Object = DataSource->AsUObject(); TSharedPtr< FPropertyPath > PropertyPath = DataSource->AsPropertyPath(); if ( Object.IsValid() ) { if ( Object->IsA( UProperty::StaticClass() ) ) { const UProperty* Property = Cast< UProperty >( Object.Get() ); DisplayName = FText::FromString(UEditorEngine::GetFriendlyName(Property)); } else { DisplayName = FText::FromString(Object->GetFName().ToString()); } } else if ( PropertyPath.IsValid() ) { //@todo unify this logic with all the property editors [12/11/2012 Justin.Sargent] FString NewName; bool FirstAddition = true; const FPropertyInfo* PreviousPropInfo = NULL; for (int PropertyIndex = 0; PropertyIndex < PropertyPath->GetNumProperties(); PropertyIndex++) { const FPropertyInfo& PropInfo = PropertyPath->GetPropertyInfo( PropertyIndex ); if ( !(PropInfo.Property->IsA( UArrayProperty::StaticClass() ) && PropertyIndex != PropertyPath->GetNumProperties() - 1 ) ) { if ( !FirstAddition ) { NewName += TEXT( "->" ); } FString PropertyName = PropInfo.Property->GetDisplayNameText().ToString(); if ( PropertyName.IsEmpty() ) { PropertyName = PropInfo.Property->GetName(); const bool bIsBoolProperty = Cast<const UBoolProperty>( PropInfo.Property.Get() ) != NULL; if ( PreviousPropInfo != NULL ) { const UStructProperty* ParentStructProperty = Cast<const UStructProperty>( PreviousPropInfo->Property.Get() ); if( ParentStructProperty && ParentStructProperty->Struct->GetFName() == NAME_Rotator ) { if( PropInfo.Property->GetFName() == "Roll" ) { PropertyName = TEXT("X"); } else if( PropInfo.Property->GetFName() == "Pitch" ) { PropertyName = TEXT("Y"); } else if( PropInfo.Property->GetFName() == "Yaw" ) { PropertyName = TEXT("Z"); } else { check(0); } } } PropertyName = FName::NameToDisplayString( PropertyName, bIsBoolProperty ); } NewName += PropertyName; if ( PropInfo.ArrayIndex != INDEX_NONE ) { NewName += FString::Printf( TEXT( "[%d]" ), PropInfo.ArrayIndex ); } PreviousPropInfo = &PropInfo; FirstAddition = false; } } DisplayName = FText::FromString(*NewName); } else { DisplayName = LOCTEXT( "InvalidColumnName", "Invalid Property" ); } }
/** Tick */ void UFluidSurfaceComponent::TickComponent( float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction ) { Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); LastDeltaTime = DeltaTime; float SimStep = 1.f / UpdateRate; static float Time = 0.0f; #if WITH_EDITOR /* Only update if checked */ if( !UpdateComponent ) return; #endif /* If this water hasn't been rendered for a while, stop updating */ if (LastRenderTime > 0 && GetWorld()->TimeSeconds - LastRenderTime > 1) return; Time += DeltaTime; if( Time > SimStep ) { Time = 0.0f; LatestVerts = !LatestVerts; /* Add ripples for actors in the water */ TArray<struct FOverlapResult> OverlappingActors; FCollisionShape CollisionShape; CollisionShape.SetBox( FluidBoundingBox.GetExtent( ) ); /* Find overlapping actors */ GetWorld()->OverlapMultiByChannel(OverlappingActors, GetComponentLocation(), GetComponentQuat(), ECC_WorldDynamic, CollisionShape, FCollisionQueryParams(false)); // @todo: handle better /* Iterate through found overlapping actors */ for( int i = 0; i < OverlappingActors.Num( ); i++ ) { TWeakObjectPtr<AActor> Actor = OverlappingActors[ i ].Actor; /* Dont care about self and modifiers */ if( Actor != NULL && !Actor->IsA( AFluidSurfaceActor::StaticClass( ) ) && !Actor->IsA( AFluidSurfaceModifier::StaticClass( ) ) ) { FVector LocalVel = GetWorldToComponent( ).TransformVector( Actor->GetVelocity( ) ); float HorizVelMag = LocalVel.Size( ); Pling( Actor->GetActorLocation( ), RippleVelocityFactor * HorizVelMag, Actor->GetSimpleCollisionRadius( ) ); } } /* Do test ripple (moving around in a circle) */ if( GIsEditor && TestRipple ) { TestRippleAng += SimStep * MyU2Rad * TestRippleSpeed; FVector WorldRipplePos, LocalRipplePos; float RippleRadius = 0.3f * ( FluidXSize - 1 ) * FluidGridSpacing; if( FluidGridType == EFluidGridType::FGT_Hexagonal ) RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing * ROOT3OVER2 ); else RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing ); LocalRipplePos.X = ( RippleRadius * FMath::Sin( TestRippleAng ) ); LocalRipplePos.Y = ( RippleRadius * FMath::Cos( TestRippleAng ) ); LocalRipplePos.Z = 0.f; WorldRipplePos = ComponentToWorld.TransformPosition( LocalRipplePos ); Pling( WorldRipplePos, TestRippleStrength, TestRippleRadius ); } /* Add modifier effects */ for( int i = 0; i < Modifiers.Num( ); i++ ) { if( Modifiers[ i ] && Modifiers[ i ]->Active ) Modifiers[ i ]->Update( DeltaTime ); } /* Need to send new dynamic data */ MarkRenderDynamicDataDirty( ); } }
void FPropertyTable::UpdateColumns() { if( Orientation == EPropertyTableOrientation::AlignPropertiesInColumns) { TMultiMap< UProperty*, TSharedRef< IPropertyTableColumn > > ColumnsMap; for (int ColumnIdx = 0; ColumnIdx < Columns.Num(); ++ColumnIdx) { TSharedRef< IDataSource > DataSource = Columns[ColumnIdx]->GetDataSource(); TSharedPtr< FPropertyPath > PropertyPath = DataSource->AsPropertyPath(); if( PropertyPath.IsValid() && PropertyPath->GetNumProperties() > 0 ) { ColumnsMap.Add(PropertyPath->GetRootProperty().Property.Get(), Columns[ColumnIdx]); } } Columns.Empty(); if ( ShowRowHeader ) { TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableRowHeaderColumn( SharedThis( this ) ) ); Columns.Add( NewColumn ); } if ( ShowObjectName ) { TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableObjectNameColumn( SharedThis( this ) ) ); NewColumn->SetFrozen( true ); Columns.Add( NewColumn ); } TArray< TWeakObjectPtr< UStruct > > UniqueTypes; TArray< int > TypeCounter; for( auto ObjectIter = SourceObjects.CreateConstIterator(); ObjectIter; ++ObjectIter ) { auto Object = *ObjectIter; if( !Object.IsValid() ) { continue; } const TSharedRef< FObjectPropertyNode > RootObjectNode = GetObjectPropertyNode( Object ); TWeakObjectPtr< UStruct > Type; if ( RootPath->GetNumProperties() == 0 ) { Type = RootObjectNode->GetObjectBaseClass(); } else { const TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, RootObjectNode ); if ( !PropertyNode.IsValid() ) { continue; } const TWeakObjectPtr< UProperty > Property = PropertyNode->GetProperty(); if ( !Property.IsValid() || !Property->IsA( UStructProperty::StaticClass() ) ) { continue; } UStructProperty* StructProperty = Cast< UStructProperty >( Property.Get() ); Type = StructProperty->Struct; } if ( !Type.IsValid() ) { continue; } int FoundIndex = -1; if ( UniqueTypes.Find( Type, /*OUT*/FoundIndex ) ) { TypeCounter[ FoundIndex ] = TypeCounter[ FoundIndex ] + 1; continue; } UniqueTypes.Add( Type ); TypeCounter.Add( 1 ); } if ( UniqueTypes.Num() > 0 ) { int HighestCountIndex = 0; int HighestCount = 0; for (int Index = 0; Index < TypeCounter.Num(); Index++) { if ( TypeCounter[Index] > HighestCount ) { HighestCountIndex = Index; HighestCount = TypeCounter[Index]; } } TWeakObjectPtr< UStruct > PrimaryType = UniqueTypes[ HighestCountIndex ]; for (TFieldIterator<UProperty> PropertyIter( PrimaryType.Get(), EFieldIteratorFlags::IncludeSuper); PropertyIter; ++PropertyIter) { TWeakObjectPtr< UProperty > Property = *PropertyIter; if ( PropertyIter->HasAnyPropertyFlags(CPF_AssetRegistrySearchable) ) { TArray< TSharedRef< IPropertyTableColumn > > MapResults; ColumnsMap.MultiFind(Property.Get(), MapResults); if(MapResults.Num() > 0) { for (int MapIdx = 0; MapIdx < MapResults.Num(); ++MapIdx) { Columns.Add(MapResults[MapIdx]); } } else { TSharedRef< IPropertyTableColumn > NewColumn = CreateColumn( Property ); Columns.Add( NewColumn ); } } } } } else { Columns.Empty(); if( SourceObjects.Num() > 0 ) { UClass* ObjectClass = SourceObjects[0]->GetClass(); TSharedRef< IPropertyTableColumn > HeadingColumn = MakeShareable( new FPropertyTablePropertyNameColumn( SharedThis( this ) ) ); Columns.Add( HeadingColumn ); for( auto ObjectIter = SourceObjects.CreateConstIterator(); ObjectIter; ++ObjectIter ) { auto Object = *ObjectIter; if( Object.IsValid() ) { const TSharedRef< FObjectPropertyNode > ObjectNode = GetObjectPropertyNode( Object ); const TSharedPtr< FPropertyNode > PropertyNode = FPropertyNode::FindPropertyNodeByPath( RootPath, ObjectNode ); UProperty* Property = PropertyNode->GetProperty(); if ( Property != NULL && Property->IsA( UArrayProperty::StaticClass() ) ) { for (int ChildIdx = 0; ChildIdx < PropertyNode->GetNumChildNodes(); ChildIdx++) { TSharedPtr< FPropertyNode > ChildNode = PropertyNode->GetChildNode( ChildIdx ); FPropertyInfo Extension; Extension.Property = ChildNode->GetProperty(); Extension.ArrayIndex = ChildNode->GetArrayIndex(); TSharedRef< FPropertyPath > Path = FPropertyPath::CreateEmpty()->ExtendPath( Extension ); TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableColumn( SharedThis( this ), Object, Path ) ); Columns.Add( NewColumn ); } } else if ( Property != NULL ) { TSharedRef< IPropertyTableColumn > NewColumn = MakeShareable( new FPropertyTableColumn( SharedThis( this ), Object ) ); Columns.Add( NewColumn ); } } } } } ColumnsChanged.Broadcast(); }