Jump to content
Wulfie Reanimator

Region Position To Screen / HUD (3D to 2D Projection)

Recommended Posts

I'm like 30% sure I've posted something similar here before, but it's not in the past 10 pages at least...

Here's a pretty simple function that takes any position in the world / region, and converts it to a useful 2D-position (relative to attachment point) that can be used on the HUD.

vector World2HUD(vector region_pos)
{
    vector   cam_pos = llGetCameraPos();
    rotation cam_rot = llGetCameraRot();

    // Calculate the offset from camera to region_pos.
    // Positive X is the forward-distance to region_pos.
    // Y0 & Z0 are at the center of the screen.
    // +Y is left, +Z is up; when the HUD is at ZERO_ROTATION.
    vector relative = (region_pos - cam_pos) / cam_rot;

    vector hud;
    if (relative.x > 0) // Ahead of the camera
    {
        // "Perspective division"
        // Here, the forward-distance is used to divide the
        // two other components to "map" them to a lower dimension. (3D -> 2D)
        hud.y = relative.y / relative.x;
        hud.z = relative.z / relative.x;
    }
    return (hud * 0.87); // FOV ratio fix. ZERO_VECTOR if behind the camera.
}

An alternative calculation can be used to map the 2D coordinates so that +X is right and +Y is down (like it would be for OpenGL, etc.)

hud.x = relative.y / -relative.x;
hud.y = relative.z / -relative.x;

 

Essentially, if you're going to use this function in a HUD attachment, make sure the HUD is attached to Center or Center 2 and not rotated. If you want to use the alternative calculation, the HUD must be rotated <0, 90, 270>. Changing the orientations is not terribly difficult if you edit your attachment and display the local coordinates, so that you can tell which way the axes go.

Here is an example that tracks an avatar:

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA);
    }

    touch_start(integer n)
    {
        list   target_data = llGetObjectDetails(target, [OBJECT_POS]);
        vector target_pos = llList2Vector(target_data, 0);
        vector hud_pos = World2HUD(target_pos);

        llSetLinkPrimitiveParamsFast(1, [PRIM_POS_LOCAL, hud_pos]);
    }
}

 

Edited by Wulfie Reanimator
  • Like 4

Share this post


Link to post
Share on other sites
4 hours ago, sandi Mexicola said:

This looks interesting, but can you explain a little bit more what it does?

All it actually "does" is convert a 3D coordinate to 2D screen space.

The main purpose for this is to show something on the HUD that relates directly to something in-world.

For example, here's a simple HUD that overlays prims onto avatars when they are within view. (I used a repeating sensor and looped through each avatar.) - https://giant.gfycat.com/RepentantKlutzyBoar.webm

Edited by Wulfie Reanimator

Share this post


Link to post
Share on other sites
2 minutes ago, Lucia Nightfire said:

Looks like another take on the old HUD Dots Radar scripts.

Apparently, and it doesn't surprise me that somebody did it first. My function is based on very basic graphics-programming mathematics. The viewer uses basically the same calculation for displaying the HUD objects themselves.

The math in that version is quite a bit more obscure, though.

Share this post


Link to post
Share on other sites
On 12/15/2019 at 7:18 PM, Lucia Nightfire said:

Looks like another take on the old HUD Dots Radar scripts.

Oh, my. I had forgotten all about that one. I wrote my own routine a couple of years ago, as I'm sure others have done.  It never hurts to reinvent the wheel, though. New functions become available and -- more to the point-- fresh eyes often see cleaner approaches.  I like this one.

  • Like 1
  • Thanks 2

Share this post


Link to post
Share on other sites
On 12/17/2019 at 9:15 PM, Rolig Loon said:

Oh, my. I had forgotten all about that one. I wrote my own routine a couple of years ago, as I'm sure others have done.  It never hurts to reinvent the wheel, though. New functions become available and -- more to the point-- fresh eyes often see cleaner approaches.  I like this one.

My fascination with scripting this last few years was thanks to YOU, Rolig Loon. I learnt HEAPS from your work and when that work vanished, years of it,  upon the demise of sluniverse, I was gutted. 

Edited by rasterscan

Share this post


Link to post
Share on other sites
On 12/15/2019 at 9:25 AM, Wulfie Reanimator said:

return (hud * 0.87); // FOV ratio fix. ZERO_VECTOR if behind the camera.

Will this break if someone changes their FOV with Ctrl + 0?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...