Untitled

something with getScreenFromWorldPosition
mail@pastecode.io avatar
unknown
lua
2 years ago
3.1 kB
1
Indexable
Never
local function get_screen_coordinates(wx, wy, wz)
    local camMatArray = getElementMatrix(getCamera());
    local camMat_right = camMatArray[1];
    local camMat_forward = camMatArray[2];
    local camMat_up = camMatArray[3];
    local camMat_pos = camMatArray[4];
    local camMat = Matrix();
    local sW, sH = guiGetScreenSize();
    local s_ratio = sH / sW;
    local _,_,_,_,_,_,_,fov = getCameraMatrix();
    local fovRad = math.rad(fov/2);
    local tanfov = math.tan(fovRad);
    local farclip = getFarClipDistance();
    camMat:setForward(Vector3(camMat_forward[1], camMat_forward[2], camMat_forward[3]));
    camMat:setRight(Vector3(camMat_right[1] * tanfov, camMat_right[2] * tanfov, camMat_right[3] * tanfov));
    camMat:setUp(Vector3(camMat_up[1] * tanfov * s_ratio, camMat_up[2] * tanfov * s_ratio, camMat_up[3] * tanfov * s_ratio));
    camMat:setPosition(Vector3(camMat_pos[1], camMat_pos[2], camMat_pos[3]));
    
    local invCamMat = camMat:inverse();
    
    local invVec = invCamMat:transformPosition(wx, wy, wz);
    
    local function to_real_coord(val)
        return ( val / 2 ) + 1/2;
    end
    
    local ratWidth, depthDist, ratHeight = invVec.x, invVec.y, invVec.z;
  
    -- Screen top is -1 but should be 1 to match the up vector perception.
    ratHeight = -ratHeight;

    if (depthDist > 0) then
        ratWidth = ratWidth / depthDist;
        ratHeight = ratHeight / depthDist;
        dxDrawText( "w: " .. ratWidth .. ", h: " .. ratHeight..", scale;"..depthDist, 100, 200 )
        if (math.abs(ratWidth) <= 1) and (math.abs(ratHeight) <= 1) then
            return to_real_coord(ratWidth), to_real_coord(ratHeight), true;
        end
    end
    
    if (ratWidth == 0) and (ratHeight == 0) then
        return 1/2, 1/2;
    elseif (ratWidth == 0) then
        return 1/2, to_real_coord(1 / ratHeight);
    elseif (ratHeight == 0) then
        return to_real_coord(1 / ratWidth), 1/2;
    end
    
    local dist_to_width = math.abs(1 / ratWidth);
    local dist_to_height = math.abs(1 / ratHeight);
    
    local scale_dist = math.min(dist_to_width, dist_to_height);
    
    ratWidth = ratWidth * scale_dist;
    ratHeight = ratHeight * scale_dist;
    
    return to_real_coord(ratWidth), to_real_coord(ratHeight), false;
end

addEventHandler("onClientRender", root,
    function()
        local wx, wy, wz = 0, 0, 10;
        
        local screenRelX, screenRelY, isOnScreen = get_screen_coordinates(wx, wy, wz);
        
        dxDrawText( "relX: " .. screenRelX .. ", relY: " .. screenRelY, 100, 300 );
        dxDrawText( "is on screen: " .. tostring(isOnScreen), 100, 320 );

        local screenWidth, screenHeight = guiGetScreenSize();
        
        local screenX, screenY = screenRelX * screenWidth, screenRelY * screenHeight;
        if isOnScreen then
            screenX, screenY = getScreenFromWorldPosition(wx, wy, wz)
        end
        dxDrawRectangle( screenX - 25, screenY - 25, 50, 50, 0xFFFFFFFF );
    end
);