Jump to content

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


Wulfie Reanimator
 Share

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

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

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
Link to comment
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
Link to comment
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.

Link to comment
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
Link to comment
Share on other sites

  • 2 weeks later...
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
Link to comment
Share on other sites

  • 4 months later...
You are about to reply to a thread that has been inactive for 1437 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...