asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Problem having elements in world space.

13 Jul 2020, 05:26

I'm trying to have a canvas for all of the elements that need to pretend like they exist in the world space (health bars, etc).

I'm having a problem with how the Canvas.Left & Canvas.Top interacts with RenderTransformOrigin. It seems that, despite being set to 0.5, 0.5, the canvas position is always the top left corner. However, when a rotate transform is set to it, it will rotate from the center like it is supposed to do.

The element:
 <Grid
            
                        Width="250"
                        Height="100"
                        Background="Black"
                        RenderTransformOrigin="0.5, 0.5">
                        <Grid.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform ScaleX="{Binding Scale}" ScaleY="{Binding Scale}" />
                            </TransformGroup>
                        </Grid.RenderTransform>
                        <TextBlock Text="{Binding ElementName=IDK, Path=ActualWidth}" />
                    </Grid>
This is inside an ItemsControl, so the canvas's left & top are being set in the ItemsContainerStyle (to Position shown below this).

How I get the position:
            var point = Camera.main.WorldToViewportPoint(Viewer.Behavior.transform.position);

            Scale = _zoomBehavior.DefaultZoom / _zoomBehavior.Zoom;

            var noesisSize = new Vector2(3100, 1560);

            point *= noesisSize;

            var position = new Vector2f(point.x, noesisSize.y - point.y);
            
            Position = position;
Image is what it looks like when the scale is 1, and Image is the scale at two (from zooming out). You can see that the element is now off from its position. It seems not only that the render origin isn't setting the control to the center, but it becomes offset once a scale is set.
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: Problem having elements in world space.

13 Jul 2020, 05:28

 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Problem having elements in world space.

13 Jul 2020, 11:16

That is correct, Canvas.Left and Canvas.Top always specify the position of the top-left corner of the child with respect to the top-left corner of the Canvas. Those properties doesn't have anything to do with RenderTransformOrigin, which only affects the transformations specified in RenderTransform property.

You can use ActualWidth and ActualHeight to translate the item position to its center with a binding converter:
<TranslateTransform
  X="{Binding ActualWidth, ElementName=TheItem, Converter={StaticResource MultiplierConverter}, ConverterParameter=-0.5}"
  Y="{Binding ActualHeight, ElementName=TheItem, Converter={StaticResource MultiplierConverter}, ConverterParameter=-0.5}"/>
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: Problem having elements in world space.

13 Jul 2020, 22:40

I see, thank you for the information! I also had the ScaleTransform after the TranslateTransform, but making the ScaleTransform apply first made it work correctly.

Is there a proper place to update the positions so it doesn't look like the elements are gliding when the camera moves? I tried putting it right before Noesis renders, but it seems to still have that floating look.
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Problem having elements in world space.

14 Jul 2020, 01:02

You want that world space elements move when camera moves, so everytime camera changes you need to update UI elements position before the View is Updated, so they are in sync.
Are you working with Unity? We update Noesis View during LateUpdate() message, so doing your position calculations during normal Update() should be fine.
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: Problem having elements in world space.

14 Jul 2020, 07:15

Hm, I'm updating them in a normal Update, but it seems to still float around. Yes, I'm using Unity. You can see it here: https://files.catbox.moe/k0q2a2.mp4

Also, is this performance normal? Setting the positions of the elements, which are each binded to Canvas.Left/Right, seem to severely hurt my framerate: https://i.imgur.com/5wqXgTN.png I'm only setting the position if it's different from the last, so this only happens when the object or camera moves. You can see that there are only 16 elements in the scene from the profiler.

Some frames it spikes really bad: https://i.imgur.com/Fwnw7AR.png
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Problem having elements in world space.

14 Jul 2020, 12:47

If updates to the map and UI elements positions occur in the same Update they should not lag like that. Can you verify that the same offset is applied to both the map and UI elements position in the same frame?

Is it possible that you are exposing a struct object for the position and binding using something like {Binding Pos.X}? That can generate a lot of boxings and GC.Allocs when updating per frame.
In this scenario it is better to expose the positions as independent X and Y properties and bind directly {Binding PosX}. Please let me know if that improves the performance.
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: Problem having elements in world space.

15 Jul 2020, 09:44

I made sure to have execution order for the behavior that is updating them to be the last one. If noesis renders on lateupdate, I have no idea why it would do this!

That did help! Is this performance normal? https://i.imgur.com/HpTlwHe.png It's around 2 ms to update both x & y for 23 elements. That seems high to me, but maybe it will be better in a release build...
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Problem having elements in world space.

15 Jul 2020, 12:00

I made sure to have execution order for the behavior that is updating them to be the last one. If noesis renders on lateupdate, I have no idea why it would do this!
I created the following test that translates a plane in 3D and some UI elements, you can see they move in sync:
There must be something different in your code that produces that lag in the render of the UI elements.
That did help! Is this performance normal? https://i.imgur.com/HpTlwHe.png It's around 2 ms to update both x & y for 23 elements. That seems high to me, but maybe it will be better in a release build...
It is not normal, we would expect hundreds of items being able to update under 1 ms, so this is something we need to investigate. But playing with a big number of items in my example I noticed that using "Deep Profile" in Unity highly affects performance calculations (from 0.88ms updating 100 items per frame, to 3.43ms with Deep Profile). Are those 2ms for 23 elements with Deep Profile enabled?
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: Problem having elements in world space.

16 Jul 2020, 00:56

Thank you so much for the example! I am sure I will figure it out using this.

Yes, that was in deep profile. Without deep profile it's more like 13 @ .50ms which is a lot better!

Who is online

Users browsing this forum: No registered users and 35 guests