x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to get the screen location of a viewport?

Hello everyone!

I'm currently implementing a plugin and I need to transform some coordinates in operating system screen space to the active viewport. I've gotten as far as finding a reference to the viewport I'm interested in:
GEngine->GameViewport->Viewport

I'm guessing this will always resolve to the viewport in question (disregarding any potential situations where it might be null). The question then becomes; How do I transform my screen coordinates to local coordinates in this viewport?

I first approached the question from the mouse angle. Since the unreal engine somehow is able to transform the mouse coordinates (expressed in "operating system screen space") to viewport space coordinates, I should be able to piggyback on that code to transform my coordinates... right?

Well it turned out to not be that easy. I think I've found the part of the code that does this, in SceneViewport.cpp:


void FSceneViewport::GetMousePos( FIntPoint& MousePosition, const bool bLocalPosition )
{
    if (bLocalPosition)
    {
        MousePosition = CachedMousePos;
    }
    else
    {
        const FVector2D AbsoluteMousePos = CachedGeometry.LocalToAbsolute(FVector2D(CachedMousePos.X, CachedMousePos.Y));
        MousePosition.X = AbsoluteMousePos.X;
        MousePosition.Y = AbsoluteMousePos.Y;
    }
}

This class is the actual type of GEngine->GameViewport->Viewport it seems.
The problem here is that CachedGeometry is private, and I can't find a good way to get access to it. I'm currently trying to find a way to intercept CachedGeometry before it reaches the SceneViewport class, but it's proving to be hard. I've tried a few hacks to subvert the encapsulation system to see if it could work, and it seems like it, but it's hardly a good solution.

Does anyone know of a better solution, or of a good way to make this work?


UPDATE:

Rama suggested using the:

     /** Transforms a point from world-space to the view's screen-space. */
     FVector4 WorldToScreen(const FVector& WorldPoint) const;
 
     /** Transforms a point from the view's screen-space to world-space. */
     FVector ScreenToWorld(const FVector4& ScreenPoint) const;
 
     /** Transforms a point from the view's screen-space into pixel coordinates relative to the view's X,Y. */
     bool ScreenToPixel(const FVector4& ScreenPoint,FVector2D& OutPixelLocation) const;
 
     /** Transforms a point from pixel coordinates relative to the view's X,Y (left, top) into the view's screen-space. */
     FVector4 PixelToScreen(float X,float Y,float Z) const;
 
     /** Transforms a point from the view's world-space into pixel coordinates relative to the view's X,Y (left, top). */
     bool WorldToPixel(const FVector& WorldPoint,FVector2D& OutPixelLocation) const;
 
     /** Transforms a point from pixel coordinates relative to the view's X,Y (left, top) into the view's world-space. */
     FVector4 PixelToWorld(float X,float Y,float Z) const;

Class of functions on FSceneView, but the screen referenced here is just another coordinate system inside the viewport itself, and are not related to the O/S screen pixels.

Best regards, Temaran

Product Version: Not Selected
Tags:
more ▼

asked May 23 '14 at 07:53 PM in C++ Programming

avatar image

Temaran
78 5 5 12

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

I haven't tried it myself, but I'm pretty sure you need FViewport::ViewportToVirtualDesktopPixel (https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/FViewport/ViewportToVirtualDesktopPixel/index.html)

more ▼

answered Dec 25 '14 at 03:05 PM

avatar image

Nevermind
76 1 7 115

avatar image Temaran Dec 25 '14 at 04:43 PM

Haha, I'd completely forgotten about this thread. I was the one who added that function to the engine a couple of months ago, but ty anyways for taking the time :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

SceneView Screen to Pixel

If you can get your FSceneView, then you want these two functions:

SceneManagement.h

 bool FSceneView::ScreenToPixel(const FVector4& ScreenPoint,FVector2D& OutPixelLocation) const

 FVector4 FSceneView::PixelToScreen(float InX,float InY,float Z) const


Rama

more ▼

answered May 25 '14 at 01:30 AM

avatar image

Rama
10.6k 446 346 1088

avatar image Temaran May 25 '14 at 02:22 AM

Very nice, I'll definately look into this!

Can't believe I missed these two functions, I was grepping around for "ToScreen" etc, but I must have overlooked it. Thank you Rama!

avatar image Temaran May 25 '14 at 08:43 AM

And if someone is wondering, the easiest way to get the sceneview is probably:

ULocalPlayer* LocalPlayer = Cast(Player);

 if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
 {
     // Create a view family for the game viewport
     FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
         LocalPlayer->ViewportClient->Viewport,
         GetWorld()->Scene,
         LocalPlayer->ViewportClient->EngineShowFlags )
         .SetRealtimeUpdate(true) );

     // Calculate a view where the player is to update the streaming from the players start location
     FVector ViewLocation;
     FRotator ViewRotation;
     FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );

     if (SceneView)
     {
         SceneView->ScreenToPixel(PROPERARGS);
     }
 }

avatar image Temaran May 26 '14 at 10:10 AM

After running a few tests, it seems that this wasn't what I needed after all. The screen referenced in these function names are just another coordinate system in the viewport it seems, not the actual physical screen.

My quest for a way to properly do this continues!

Thank you for the idea though :)

avatar image Beibei Aug 13 '14 at 07:17 AM

I'm also very interested in the answer to this question, have you found out a solution?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question