From 392d3248636319dd4e0e42bc119b5d89d3990b9d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 16 Aug 2025 04:31:17 +0100 Subject: [PATCH] add llWorldPosToHUD --- .../Shared/Api/Implementation/LSL_Api.cs | 62 +++++++++++++++++++ .../Shared/Api/Interface/ILSL_Api.cs | 1 + .../Shared/Api/Runtime/LSL_Stub.cs | 5 ++ 3 files changed, 68 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index efaac552c8..aed5289851 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -19609,6 +19609,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 0; } + public LSL_Vector llWorldPosToHUD(LSL_Vector wp) + { + if(!m_host.ParentGroup.IsAttachment) + return LSL_Vector.Zero; + + uint atp = m_host.ParentGroup.AttachmentPoint; + if(atp < (uint)AttachmentPoint.HUDCenter2 || atp > (uint)AttachmentPoint.HUDBottomRight) + return LSL_Vector.Zero; + + if (m_item.PermsGranter.NotEqual(m_host.OwnerID) || + (m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + Error("llGetCameraPos", "No permissions to track the camera"); + return LSL_Vector.Zero; + } + + ScenePresence sp = World.GetScenePresence(m_host.OwnerID); + if(sp is null) + return LSL_Vector.Zero; + + Vector3 totarget = (Vector3)wp - sp.CameraPosition; + totarget.Normalize(); + float at = totarget.Dot(sp.CameraAtAxis); + float left = totarget.Dot(sp.CameraLeftAxis); + float up = totarget.Dot(sp.CameraUpAxis); + + if(atp != (uint)AttachmentPoint.HUDCenter2 && atp != (uint)AttachmentPoint.HUDCenter2) + { + int h = sp.ControllingClient.viewHeight; + if(h > 0) + { + float aspect = 0.5f * (float)sp.ControllingClient.viewWidth / h; + switch(atp) + { + case (uint)AttachmentPoint.HUDTop: + up -= 0.5f; + break; + case (uint)AttachmentPoint.HUDTopLeft: + up -= 0.5f; + left -= aspect; + break; + case (uint)AttachmentPoint.HUDTopRight: + up -= 0.5f; + left += aspect; + break; + case (uint)AttachmentPoint.HUDBottom: + up += 0.5f; + break; + case (uint)AttachmentPoint.HUDBottomLeft: + up += 0.5f; + left -= aspect; + break; + case (uint)AttachmentPoint.HUDBottomRight: + up += 0.5f; + left += aspect; + break; + } + } + } + return new(at > 0 ? 1 : -1, left, up); + } + static string HMAC_SHA224(string key, string message) { const int blockSize = 64; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 21248069a2..0d7d691d25 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -536,5 +536,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llComputeHash(LSL_String message, LSL_String algo); LSL_String llGetRenderMaterial(LSL_Integer face); LSL_Integer llIsLinkGLTFMaterial(LSL_Integer linknum, LSL_Integer face); + LSL_Vector llWorldPosToHUD(LSL_Vector WorldPosition); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 2cc373565b..99917316b6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -2894,5 +2894,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llIsLinkGLTFMaterial(linknum, face); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_Vector llWorldPosToHUD(LSL_Vector WorldPosition) + { + return m_LSL_Functions.llWorldPosToHUD(WorldPosition); + } } }