Jump to content

Curiosity, why does this work - FindScreenWidth Example


ValKalAstra
 Share

You are about to reply to a thread that has been inactive for 640 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

So, in my endeavour of finding "simple" ideas that should be easy to implement - but obviously never are, I came across the need to determine the width and height of the display. The Wiki supplies an example for screen width here: https://wiki.secondlife.com/wiki/FindScreenWidth

//Find Screen Width
//By Darwin Recreant

default
{
    touch_start(integer total_number)
    {
        vector scale = llGetScale();
        vector off_point = llGetLocalPos();
        vector face_pos = llDetectedTouchST(0);
        vector screen_pos = llDetectedTouchPos(0);
        
        float screen_width = ((face_pos.x-.5)*scale.y-off_point.y+screen_pos.y)*2;
        
        llOwnerSay((string)screen_width);
    }
}

Cool! Except I've got no bloody idea why it works. Before we get into this, please know that I am a nightmare at math. Either way, I could use someone walking me through this. I don't quite understand why this works. I'll lay down my thought processes so far:

I think it uses a caveat of the llDetectedTouchPos Function to get the difference between the corner of the screen and the centre. Namely: "HUD attachments currently return coordinates relative to the center of the screen rather than the attachment point. SVC-3425". Furthermore and where my brain starts hurting: I think, with llDetectedTouch x is horizontal, y is vertical, z is depth but with llDetectedTouchPos, x is depth, y is horizontal and z is vertical. Furthermore, llDetectedTouchST uses an origin at the bottom left corner of the prim and I think the subtraction of 0.5 moves it so that the origin point is moved to the centre - since a prim attached to a screen corner will also have it's centre at 0, question maaaaaark? Yeah I am fumbling in the dark.

Furthermore, if I use a prim with measurements of 1, 1, 1 and leave it at precisely 0, then both scale and off_point should play no role. Offset will be 0 and scale will just multiply by 1 and the final multiplication by 2 is because we don't want the distance to the centre but the far edge. So that basically reduces the formula down to: face_pos.x-0.5+screen_pos.y

So if I wanted the height, it should be face_pos.y-0.5+screen_pos.z, no? Well apparently not as the result is wrong. So obviously I'm not understanding some fundamental part of it.

If I look at the value outputs, for example:

Face Pos: <0.90000, 0.11111, 0.00000>
Screen Pos: <-0.49994, 0.56970, 0.11111>
Width: 1.939394

I can see how it gets the width but not how to maybe get the height. Which in my example would need to be around ~1.091 (or 0.54 before*2). I mean ultimately, I can just get the height via aspect ratio but I'd like to understand why the function works. Curiosity, maybe, a desire to learn. Bit embarrassed because yeah, math was never my strength. So... you can probably see why my math teachers started drinking.

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

49 minutes ago, Ron Khondji said:

It seems to me that if you have a vector from a corner to the center of the screen, and multiply that by 2, you get the diagonal instead of the width of the screen. But my math may be worse than yours.

Yeh, I thought that was what the -0.5 was for. But... honestly I've managed to think myself into a corner.

  • Like 1
Link to comment
Share on other sites

Here's how I go about figuring out how someone's math works. I break down every calculation into its own variable, usually with a place holder name like "idk1", "idk2", and rename them as I figure out the exact purpose.

default
{
    touch_start(integer total_number)
    {
        vector TouchST = llDetectedTouchST(0);
        vector TouchPos = llDetectedTouchPos(0);
        vector LocalPos = llGetLocalPos();
        vector Scale = llGetScale();

        float click_surface = TouchST.x;
        float prim_width = Scale.y;
        float prim_horizontal_offset = LocalPos.y;
        float screen_center_offset = TouchPos.y;

        float click_relative = (click_surface - 0.5); // relative to surface center
        float click_adjusted = (click_relative * prim_width); // account for prim size
        float without_offset = (click_adjusted - prim_horizontal_offset);
        float distance_to_center = (without_offset + screen_center_offset);
        float screen_width = (distance_to_center * 2);

        llOwnerSay((string)["\n",
            "click_surface\t", click_surface, "\n",
            "prim_width\t", prim_width, "\n",
            "prim_horizontal_offset\t", prim_horizontal_offset, "\n",
            "screen_center_offset\t", screen_center_offset, "\n",
            "click_relative\t", click_relative, "\n",
            "click_adjusted\t", click_adjusted, "\n",
            "without_offset\t", without_offset, "\n",
            "distance_to_center\t", distance_to_center, "\n",
            "screen_width\t", screen_width, "\n"
        ]);
    }
}

// click_surface          0.700401
// prim_width             0.200000
// prim_horizontal_offset 0.000000
// screen_center_offset   0.921844
// click_relative         0.200401
// click_adjusted         0.040080
// without_offset         0.040080
// distance_to_center     0.961924
// screen_width           1.923848

From there, it's pretty easy to see what's going on. I used top-left corner but the same logic applies regardless.

  1. Subtract 0.5 from TouchST.
    • The original value will always be in the range 0.0 to 1.0. This will change the range to -0.5 to 0.5.
    • Since the prim should be attached to a corner, the center of the prim/surface will be exactly on the corner.
  2. Multiply by prim width.
    • Different people might use differently sized prims, which would skew the numbers.
    • My default cube is 0.2 meters wide.

At this point you have a distance from the corner.

  1. Subtract the prim's local position.
    • Otherwise the math would break if the prim was moved from the corner.
  2. Add the distance to the screen center.
    • TouchPos caveat: "HUD attachments currently return coordinates relative to the center of the screen rather than the attachment point. SVC-3425"

At this point you have a distance from the corner and the center of the screen.

Multiplying by two theoretically gives you the full distance across the screen, but the number is a little off for some reason. (1.9238 instead of expected 1.920. Seems like TouchPos is a bit inaccurate.)

And based on that knowledge, the calculation could be simplified if you used a 1x1x1 cube at the corner:

float screen_width = (TouchST.x - 0.5 + TouchPos.y) * 2;

 

Edited by Wulfie Reanimator
  • Like 1
  • Thanks 2
Link to comment
Share on other sites

Regarding screen height, 1 meter seems to represent the full height of a viewer's screen - and I believe that includes the menu and toolbars.

If you edit-select a HUD, you can scroll the mouse wheel to zoom the HUD view out. There will be a white rectangle that shows the borders of the screen under normal circumstances and a 1m tall prim vertically centered in the view will line up with the bottom, and ever so slightly expand past the top (I'm guessing that being the bit normally covered by the menu bar).

Interestingly, a 10 meter tall prim will appear to fully cover the screen's height when the HUD view is edit-zoomed all the way out.

  • Like 2
Link to comment
Share on other sites

20 hours ago, Fenix Eldritch said:

Regarding screen height, 1 meter seems to represent the full height of a viewer's screen - and I believe that includes the menu and toolbars.

If you edit-select a HUD, you can scroll the mouse wheel to zoom the HUD view out. There will be a white rectangle that shows the borders of the screen under normal circumstances and a 1m tall prim vertically centered in the view will line up with the bottom, and ever so slightly expand past the top (I'm guessing that being the bit normally covered by the menu bar).

Interestingly, a 10 meter tall prim will appear to fully cover the screen's height when the HUD view is edit-zoomed all the way out.

Yeah, the entire HUD area is scaled based on the vertical height of the window.

This can be seen if you resize the viewer window only horizontally (all HUD objects stay the same size), and only vertically (everything gets rescaled). Consequently you can't use the same method to calculate the screen height because TouchPos will always return -0.5 to 0.5 for height, regardless of the actual height of the window.

Edited by Wulfie Reanimator
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

25 minutes ago, Wulfie Reanimator said:

Yeah, the entire HUD area is scaled based on the vertical height of the window.

This can be seen if you resize the viewer window only horizontally (all HUD objects stay the same size), and only vertically (everything gets rescaled). Consequently you can't use the same method to calculate the screen height because TouchPos will always return 0.0 to 0.5 for the screen height, regardless of the actual height of the window.

Is that to prevent stretchies (mismatch in horizontal vs. vertical scales)?

  • Like 1
Link to comment
Share on other sites

2 hours ago, Love Zhaoying said:

Is that to prevent stretchies (mismatch in horizontal vs. vertical scales)?

It's complicated, but I don't think so.

The HUD shouldn't necessarily have to depend on vertical (or horizontal) scaling in order to be displayed correctly. I think it's just the way the HUD attachment points are set up, but I don't know.

  • Like 2
Link to comment
Share on other sites

4 hours ago, Wulfie Reanimator said:

It's complicated, but I don't think so.

The HUD shouldn't necessarily have to depend on vertical (or horizontal) scaling in order to be displayed correctly. I think it's just the way the HUD attachment points are set up, but I don't know.

Aspect ratio, that's the term I was looking for.

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 640 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...