コード例 #1
0
void FEditorLiveStreaming::BroadcastStatusCallback( const FLiveStreamingStatus& Status )
{
	TSharedPtr< SNotificationItem > Notification( NotificationWeakPtr.Pin() );
	if( Notification.IsValid() )
	{
		// Don't bother clobbering existing message with text about web cam starting/stopping, unless we're already broadcasting.
		// We want to make sure people see the persistent text about login state.
		if( SubmittedVideoFrameCount > 0 ||
			( Status.StatusType != FLiveStreamingStatus::EStatusType::WebCamStarted &&
			  Status.StatusType != FLiveStreamingStatus::EStatusType::WebCamStopped &&
			  Status.StatusType != FLiveStreamingStatus::EStatusType::WebCamTextureNotReady &&
			  Status.StatusType != FLiveStreamingStatus::EStatusType::WebCamTextureReady &&
			  Status.StatusType != FLiveStreamingStatus::EStatusType::ChatConnected &&
			  Status.StatusType != FLiveStreamingStatus::EStatusType::ChatDisconnected ) )
		{
			Notification->SetText( Status.CustomStatusDescription );
		}
	}
	else
	{
		// Only spawn a notification if we're actually still trying to broadcast, not if we're stopping broadcasting.  We don't want
		// to revive our notification that we intentionally expired.
		if( bIsBroadcasting )
		{
			FNotificationInfo Info( Status.CustomStatusDescription );
			Info.FadeInDuration = 0.1f;
			Info.FadeOutDuration = 0.5f;
			Info.ExpireDuration = 1.5f;
			Info.bUseThrobber = false;
			Info.bUseSuccessFailIcons = true;
			Info.bUseLargeFont = true;
			Info.bFireAndForget = false;
			Info.bAllowThrottleWhenFrameRateIsLow = false;
			NotificationWeakPtr = FSlateNotificationManager::Get().AddNotification( Info );
		}
	}

	Notification = NotificationWeakPtr.Pin();
	if( Notification.IsValid() )
	{
		SNotificationItem::ECompletionState State = SNotificationItem::CS_Pending;
		if( Status.StatusType == FLiveStreamingStatus::EStatusType::Failure )
		{
			State = SNotificationItem::CS_Fail;
		}
		else if( Status.StatusType == FLiveStreamingStatus::EStatusType::BroadcastStarted ||
				 Status.StatusType == FLiveStreamingStatus::EStatusType::WebCamStarted ||
				 Status.StatusType == FLiveStreamingStatus::EStatusType::ChatConnected )
		{
			State = SNotificationItem::CS_Success;
		}

		Notification->SetCompletionState( State );
	}

	// If the web cam just turned on, then we'll go ahead and show it
	if( Status.StatusType == FLiveStreamingStatus::EStatusType::WebCamTextureReady )
	{	
		bool bIsImageFlippedHorizontally = false;
		bool bIsImageFlippedVertically = false;
		UTexture2D* WebCamTexture = LiveStreamer->GetWebCamTexture( bIsImageFlippedHorizontally, bIsImageFlippedVertically );
		if( ensure( WebCamTexture != nullptr ) )
		{
			IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( TEXT( "MainFrame" ) );
			check( MainFrameModule.IsWindowInitialized() );
			auto RootWindow = MainFrameModule.GetParentWindow();
			check( RootWindow.IsValid() );

			// Allow the user to customize the image mirroring, too!
			const auto& Settings = *GetDefault< UEditorLiveStreamingSettings >();
			if( Settings.bMirrorWebCamImage )
			{
				bIsImageFlippedHorizontally = !bIsImageFlippedHorizontally;
			}

			// How many pixels from the edge of the main frame window to where the broadcast status window appears
			const int WindowBorderPadding = 50;

			// @todo livestream: Currently this window is not created as "topmost".  We don't really want it to be OS-topmost, but we do want it to be the most
			// topmost "regular" window in our application (not on top of tooltips, etc.)

			// Create a window that will show the web cam video feed
			BroadcastStatusWindow = SNew( SWindow )
				.Title( LOCTEXT( "StreamingWindowTitle", "Web Camera" ) )
				.ClientSize( FVector2D( WebCamTexture->GetSizeX(), WebCamTexture->GetSizeY() ) )
				.ScreenPosition( FVector2D( 
					RootWindow->GetRectInScreen().Right - WebCamTexture->GetSizeX() - WindowBorderPadding, 
					RootWindow->GetRectInScreen().Top +  WindowBorderPadding ) )

				// @todo livestream: Ideally the user could freely resize the window, but it gets a bit tricky to preserve the web cam aspect.  Plus, we don't really like how letterboxing/columnboxing looks with this.
				.SizingRule( ESizingRule::FixedSize )

				.AutoCenter( EAutoCenter::None )
				.bDragAnywhere( true )
				.SupportsMaximize( true )
				.SupportsMinimize( true )
				.FocusWhenFirstShown( false )
				.ActivateWhenFirstShown( false )
				.SaneWindowPlacement( false );

			WebCamDynamicImageBrush = MakeShareable( new FSlateDynamicImageBrush( 
				WebCamTexture,
				FVector2D( WebCamTexture->GetSizeX(), WebCamTexture->GetSizeY() ),
				WebCamTexture->GetFName() ) );

			// If the web cam image is coming in flipped, we'll apply mirroring to the Slate brush
			if( bIsImageFlippedHorizontally && bIsImageFlippedVertically )
			{
				WebCamDynamicImageBrush->Mirroring = ESlateBrushMirrorType::Both;
			}
			else if( bIsImageFlippedHorizontally )
			{ 
				WebCamDynamicImageBrush->Mirroring = ESlateBrushMirrorType::Horizontal;
			}
			else if( bIsImageFlippedVertically )
			{ 
				WebCamDynamicImageBrush->Mirroring = ESlateBrushMirrorType::Vertical;
			}

			// @todo livestream: Currently if the user closes the window, the camera is deactivated and it doesn't turn back on unless the broadcast is restarted.  We could allow the camera to be reactivated though.
			BroadcastStatusWindow->SetOnWindowClosed( 
				FOnWindowClosed::CreateStatic( []( const TSharedRef<SWindow>& Window, FEditorLiveStreaming* This ) 
				{
					// User closed the broadcast status window, so go ahead and shut down the web cam
					This->LiveStreamer->StopWebCam();
					This->BroadcastStatusWindow.Reset();
					This->WebCamDynamicImageBrush.Reset();
				}, 
				this ) );

			BroadcastStatusWindow->SetContent( 
				SNew( SImage )
					.Image( WebCamDynamicImageBrush.Get() )
			);

			FSlateApplication::Get().AddWindowAsNativeChild(
				BroadcastStatusWindow.ToSharedRef(), 
				RootWindow.ToSharedRef() );
		}

	}
	else if( Status.StatusType == FLiveStreamingStatus::EStatusType::WebCamTextureNotReady )
	{
		CloseBroadcastStatusWindow();
	}
}
コード例 #2
0
ファイル: EdMode.cpp プロジェクト: candyhenry/Unreal4
void FEdMode::DrawHUD(FEditorViewportClient* ViewportClient,FViewport* Viewport,const FSceneView* View,FCanvas* Canvas)
{
    // Render the drag tool.
    ViewportClient->RenderDragTool( View, Canvas );

    // Let the current mode tool draw a HUD if it wants to
    FModeTool* tool = GetCurrentTool();
    if( tool )
    {
        tool->DrawHUD( ViewportClient, Viewport, View, Canvas );
    }

    if (ViewportClient->IsPerspective() && GetDefault<ULevelEditorViewportSettings>()->bHighlightWithBrackets)
    {
        DrawBrackets( ViewportClient, Viewport, View, Canvas );
    }

    // If this viewport doesn't show mode widgets or the mode itself doesn't want them, leave.
    if( !(ViewportClient->EngineShowFlags.ModeWidgets) || !ShowModeWidgets() )
    {
        return;
    }

    // Clear Hit proxies
    const bool bIsHitTesting = Canvas->IsHitTesting();
    if ( !bIsHitTesting )
    {
        Canvas->SetHitProxy(NULL);
    }

    // Draw vertices for selected BSP brushes and static meshes if the large vertices show flag is set.
    if ( !ViewportClient->bDrawVertices )
    {
        return;
    }

    const bool bLargeVertices		= View->Family->EngineShowFlags.LargeVertices;
    const bool bShowBrushes			= View->Family->EngineShowFlags.Brushes;
    const bool bShowBSP				= View->Family->EngineShowFlags.BSP;
    const bool bShowBuilderBrush	= View->Family->EngineShowFlags.BuilderBrush != 0;

    UTexture2D* VertexTexture = GetVertexTexture();
    const float TextureSizeX		= VertexTexture->GetSizeX() * ( bLargeVertices ? 1.0f : 0.5f );
    const float TextureSizeY		= VertexTexture->GetSizeY() * ( bLargeVertices ? 1.0f : 0.5f );

    // Temporaries.
    TArray<FVector> Vertices;

    for ( FSelectionIterator It( *Owner->GetSelectedActors() ) ; It ; ++It )
    {
        AActor* SelectedActor = static_cast<AActor*>( *It );
        checkSlow( SelectedActor->IsA(AActor::StaticClass()) );

        if( bLargeVertices )
        {
            FCanvasItemTestbed::bTestState = !FCanvasItemTestbed::bTestState;

            // Static mesh vertices
            AStaticMeshActor* Actor = Cast<AStaticMeshActor>( SelectedActor );
            if( Actor && Actor->GetStaticMeshComponent() && Actor->GetStaticMeshComponent()->StaticMesh
                    && Actor->GetStaticMeshComponent()->StaticMesh->RenderData )
            {
                FTransform ActorToWorld = Actor->ActorToWorld();
                Vertices.Empty();
                const FPositionVertexBuffer& VertexBuffer = Actor->GetStaticMeshComponent()->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
                for( uint32 i = 0 ; i < VertexBuffer.GetNumVertices() ; i++ )
                {
                    Vertices.AddUnique( ActorToWorld.TransformPosition( VertexBuffer.VertexPosition(i) ) );
                }

                FCanvasTileItem TileItem( FVector2D( 0.0f, 0.0f ), FVector2D( 0.0f, 0.0f ), FLinearColor::White );
                TileItem.BlendMode = SE_BLEND_Translucent;
                for( int32 VertexIndex = 0 ; VertexIndex < Vertices.Num() ; ++VertexIndex )
                {
                    const FVector& Vertex = Vertices[VertexIndex];
                    FVector2D PixelLocation;
                    if(View->ScreenToPixel(View->WorldToScreen(Vertex),PixelLocation))
                    {
                        const bool bOutside =
                            PixelLocation.X < 0.0f || PixelLocation.X > View->ViewRect.Width() ||
                            PixelLocation.Y < 0.0f || PixelLocation.Y > View->ViewRect.Height();
                        if( !bOutside )
                        {
                            const float X = PixelLocation.X - (TextureSizeX/2);
                            const float Y = PixelLocation.Y - (TextureSizeY/2);
                            if( bIsHitTesting )
                            {
                                Canvas->SetHitProxy( new HStaticMeshVert(Actor,Vertex) );
                            }
                            TileItem.Texture = VertexTexture->Resource;

                            TileItem.Size = FVector2D( TextureSizeX, TextureSizeY );
                            Canvas->DrawItem( TileItem, FVector2D( X, Y ) );
                            if( bIsHitTesting )
                            {
                                Canvas->SetHitProxy( NULL );
                            }
                        }
                    }
                }
            }
        }
    }

    if(UsesPropertyWidgets())
    {
        AActor* SelectedActor = GetFirstSelectedActorInstance();
        if (SelectedActor != NULL)
        {
            FEditorScriptExecutionGuard ScriptGuard;

            const int32 HalfX = 0.5f * Viewport->GetSizeXY().X;
            const int32 HalfY = 0.5f * Viewport->GetSizeXY().Y;

            UClass* Class = SelectedActor->GetClass();
            TArray<FPropertyWidgetInfo> WidgetInfos;
            GetPropertyWidgetInfos(Class, SelectedActor, WidgetInfos);
            for(int32 i=0; i<WidgetInfos.Num(); i++)
            {
                FString WidgetName = WidgetInfos[i].PropertyName;
                FName WidgetValidator = WidgetInfos[i].PropertyValidationName;
                int32 WidgetIndex = WidgetInfos[i].PropertyIndex;
                bool bIsTransform = WidgetInfos[i].bIsTransform;

                FVector LocalPos = FVector::ZeroVector;
                if(bIsTransform)
                {
                    FTransform LocalTM = GetPropertyValueByName<FTransform>(SelectedActor, WidgetName, WidgetIndex);
                    LocalPos = LocalTM.GetLocation();
                }
                else
                {
                    LocalPos = GetPropertyValueByName<FVector>(SelectedActor, WidgetName, WidgetIndex);
                }

                FTransform ActorToWorld = SelectedActor->ActorToWorld();
                FVector WorldPos = ActorToWorld.TransformPosition(LocalPos);

                UFunction* ValidateFunc = NULL;
                FString FinalString;
                if(WidgetValidator != NAME_None &&
                        (ValidateFunc = SelectedActor->FindFunction(WidgetValidator)) != NULL)
                {
                    SelectedActor->ProcessEvent(ValidateFunc, &FinalString);
                }

                const FPlane Proj = View->Project( WorldPos );

                //do some string fixing
                const uint32 VectorIndex = WidgetInfos[i].PropertyIndex;
                const FString WidgetDisplayName = WidgetInfos[i].DisplayName + ((VectorIndex != INDEX_NONE) ? FString::Printf(TEXT("[%d]"), VectorIndex) : TEXT(""));
                FinalString = FinalString.IsEmpty() ? WidgetDisplayName : FinalString;

                if(Proj.W > 0.f)
                {
                    const int32 XPos = HalfX + ( HalfX * Proj.X );
                    const int32 YPos = HalfY + ( HalfY * (Proj.Y * -1.f) );
                    FCanvasTextItem TextItem( FVector2D( XPos + 5, YPos), FText::FromString( FinalString ), GEngine->GetSmallFont(), FLinearColor::White );
                    Canvas->DrawItem( TextItem );
                }
            }
        }
    }
}
コード例 #3
0
void UPaperTileMapComponent::RebuildRenderData(FPaperTileMapRenderSceneProxy* Proxy)
{
	TArray<FSpriteDrawCallRecord> BatchedSprites;
	
	if (TileMap == nullptr)
	{
		return;
	}

	FVector CornerOffset;
	FVector OffsetYFactor;
	FVector StepPerTileX;
	FVector StepPerTileY;
	TileMap->GetTileToLocalParameters(/*out*/ CornerOffset, /*out*/ StepPerTileX, /*out*/ StepPerTileY, /*out*/ OffsetYFactor);
	
	UTexture2D* LastSourceTexture = nullptr;
	FVector TileSetOffset = FVector::ZeroVector;
	FVector2D InverseTextureSize(1.0f, 1.0f);
	FVector2D SourceDimensionsUV(1.0f, 1.0f);
	FVector2D TileSizeXY(0.0f, 0.0f);

	for (int32 Z = 0; Z < TileMap->TileLayers.Num(); ++Z)
	{
		UPaperTileLayer* Layer = TileMap->TileLayers[Z];

		if (Layer == nullptr)
		{
			continue;
		}

		FLinearColor DrawColor = FLinearColor::White;
#if WITH_EDITORONLY_DATA
		if (Layer->bHiddenInEditor)
		{
			continue;
		}

		DrawColor.A = Layer->LayerOpacity;
#endif

		FSpriteDrawCallRecord* CurrentBatch = nullptr;

		for (int32 Y = 0; Y < TileMap->MapHeight; ++Y)
		{
			// In pixels
			FVector EffectiveTopLeftCorner;

			switch (TileMap->ProjectionMode)
			{
			case ETileMapProjectionMode::Orthogonal:
			default:
				EffectiveTopLeftCorner = CornerOffset;
				break;
			case ETileMapProjectionMode::IsometricDiamond:
				EffectiveTopLeftCorner = CornerOffset - StepPerTileX;
				break;
			case ETileMapProjectionMode::IsometricStaggered:
			case ETileMapProjectionMode::HexagonalStaggered:
				EffectiveTopLeftCorner = CornerOffset + (Y & 1) * OffsetYFactor;
				break;
			}

			for (int32 X = 0; X < TileMap->MapWidth; ++X)
			{
				const FPaperTileInfo TileInfo = Layer->GetCell(X, Y);

				// do stuff
				const float TotalSeparation = (TileMap->SeparationPerLayer * Z) + (TileMap->SeparationPerTileX * X) + (TileMap->SeparationPerTileY * Y);
				FVector TopLeftCornerOfTile = (StepPerTileX * X) + (StepPerTileY * Y) + EffectiveTopLeftCorner;
				TopLeftCornerOfTile += TotalSeparation * PaperAxisZ;

				const int32 TileWidth = TileMap->TileWidth;
				const int32 TileHeight = TileMap->TileHeight;


				{
					UTexture2D* SourceTexture = nullptr;

					FVector2D SourceUV = FVector2D::ZeroVector;
					if (Layer->bCollisionLayer)
					{
						if (TileInfo.PackedTileIndex == 0)
						{
							continue;
						}
						SourceTexture = UCanvas::StaticClass()->GetDefaultObject<UCanvas>()->DefaultTexture;
					}
					else
					{
						if (TileInfo.TileSet == nullptr)
						{
							continue;
						}

						if (!TileInfo.TileSet->GetTileUV(TileInfo.PackedTileIndex, /*out*/ SourceUV))
						{
							continue;
						}

						SourceTexture = TileInfo.TileSet->TileSheet;
						if (SourceTexture == nullptr)
						{
							continue;
						}
					}

					if ((SourceTexture != LastSourceTexture) || (CurrentBatch == nullptr))
					{
						CurrentBatch = (new (BatchedSprites) FSpriteDrawCallRecord());
						CurrentBatch->Texture = SourceTexture;
						CurrentBatch->Color = DrawColor;
						CurrentBatch->Destination = TopLeftCornerOfTile.ProjectOnTo(PaperAxisZ);
					}

					if (SourceTexture != LastSourceTexture)
					{
						InverseTextureSize = FVector2D(1.0f / SourceTexture->GetSizeX(), 1.0f / SourceTexture->GetSizeY());

						if (TileInfo.TileSet != nullptr)
						{
							SourceDimensionsUV = FVector2D(TileInfo.TileSet->TileWidth * InverseTextureSize.X, TileInfo.TileSet->TileHeight * InverseTextureSize.Y);
							TileSizeXY = FVector2D(TileInfo.TileSet->TileWidth, TileInfo.TileSet->TileHeight);
							TileSetOffset = (TileInfo.TileSet->DrawingOffset.X * PaperAxisX) + (TileInfo.TileSet->DrawingOffset.Y * PaperAxisY);
						}
						else
						{
							SourceDimensionsUV = FVector2D(TileWidth * InverseTextureSize.X, TileHeight * InverseTextureSize.Y);
							TileSizeXY = FVector2D(TileWidth, TileHeight);
							TileSetOffset = FVector::ZeroVector;
						}
						LastSourceTexture = SourceTexture;
					}
					TopLeftCornerOfTile += TileSetOffset;

					SourceUV.X *= InverseTextureSize.X;
					SourceUV.Y *= InverseTextureSize.Y;

					FSpriteDrawCallRecord& NewTile = *CurrentBatch;

					const float WX0 = FVector::DotProduct(TopLeftCornerOfTile, PaperAxisX);
					const float WY0 = FVector::DotProduct(TopLeftCornerOfTile, PaperAxisY);

					const FVector4 BottomLeft(WX0, WY0 - TileSizeXY.Y, SourceUV.X, SourceUV.Y + SourceDimensionsUV.Y);
					const FVector4 BottomRight(WX0 + TileSizeXY.X, WY0 - TileSizeXY.Y, SourceUV.X + SourceDimensionsUV.X, SourceUV.Y + SourceDimensionsUV.Y);
					const FVector4 TopRight(WX0 + TileSizeXY.X, WY0, SourceUV.X + SourceDimensionsUV.X, SourceUV.Y);
					const FVector4 TopLeft(WX0, WY0, SourceUV.X, SourceUV.Y);

					new (NewTile.RenderVerts) FVector4(BottomLeft);
					new (NewTile.RenderVerts) FVector4(TopRight);
					new (NewTile.RenderVerts) FVector4(BottomRight);

					new (NewTile.RenderVerts) FVector4(BottomLeft);
					new (NewTile.RenderVerts) FVector4(TopLeft);
					new (NewTile.RenderVerts) FVector4(TopRight);
				}
			}
		}
	}

	Proxy->SetBatchesHack(BatchedSprites);
}
コード例 #4
-4
static bool UpdateSelectedTexel(
	UPrimitiveComponent* Component, 
	int32 NodeIndex, 
	FLightMapRef& Lightmap, 
	const FVector& Position, 
	FVector2D InterpolatedUV, 
	int32 LocalX, int32 LocalY,
	int32 LightmapSizeX, int32 LightmapSizeY)
{
	if (Component == GCurrentSelectedLightmapSample.Component
		&& NodeIndex == GCurrentSelectedLightmapSample.NodeIndex
		&& LocalX == GCurrentSelectedLightmapSample.LocalX
		&& LocalY == GCurrentSelectedLightmapSample.LocalY)
	{
		return false;
	}
	else
	{
		// Store information about the selected texel
		FSelectedLightmapSample NewSelectedTexel(Component, NodeIndex, Lightmap, Position, LocalX, LocalY, LightmapSizeX, LightmapSizeY);

		if (IsValidRef(Lightmap))
		{
			FLightMap2D* Lightmap2D = Lightmap->GetLightMap2D();
			check(Lightmap2D);
			const FVector2D CoordinateScale = Lightmap2D->GetCoordinateScale();
			const FVector2D CoordinateBias = Lightmap2D->GetCoordinateBias();
			// Calculate lightmap atlas UV's for the selected point
			FVector2D LightmapUV = InterpolatedUV * CoordinateScale + CoordinateBias;

			int32 LightmapIndex = Lightmap2D->AllowsHighQualityLightmaps() ? 0 : 1;
			UTexture2D* CurrentLightmap = Lightmap2D->GetTexture( LightmapIndex );
			// UV's in the lightmap atlas
			NewSelectedTexel.LightmapX = FMath::TruncToInt(LightmapUV.X * CurrentLightmap->GetSizeX());
			NewSelectedTexel.LightmapY = FMath::TruncToInt(LightmapUV.Y * CurrentLightmap->GetSizeY());
			// Write the selection color to the selected lightmap texel
			WriteTexel(CurrentLightmap, NewSelectedTexel.LightmapX, NewSelectedTexel.LightmapY, GTexelSelectionColor, NewSelectedTexel.OriginalColor);

			GCurrentSelectedLightmapSample = NewSelectedTexel;
			return true;
		}
		else
		{
			UE_LOG(LogStaticLightingSystem, Log, TEXT("Texel selection failed because the lightmap is an invalid reference!"));
			return false;
		}
	}
}