From 2bb5e985740b7c6aa75cd31aa057d39d56f024b6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 3 Apr 2017 17:19:28 +0100 Subject: add EXPERIMENTAL osObjectTeleport(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer stop) --- OpenSim/Region/Framework/Scenes/Scene.cs | 31 ++++++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 85 ++++++++++++++++++++++ .../Shared/Api/Implementation/OSSL_Api.cs | 46 ++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 4 + 5 files changed, 161 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c5b082c..3b9f551 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -808,6 +808,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_minReprioritizationDistance = 32f; public bool ObjectsCullingByDistance = false; + private ExpiringCache TeleportTargetsCoolDown = new ExpiringCache(); + public AgentCircuitManager AuthenticateHandler { get { return m_authenticateHandler; } @@ -2983,15 +2985,14 @@ namespace OpenSim.Region.Framework.Scenes // Return 'true' if position inside region. public bool PositionIsInCurrentRegion(Vector3 pos) { - bool ret = false; - int xx = (int)Math.Floor(pos.X); - int yy = (int)Math.Floor(pos.Y); - if (xx < 0 || yy < 0) + int xx = (int)pos.X; + if (xx < 0 || xx >= RegionInfo.RegionSizeX) return false; - if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) - ret = true; - return ret; + int yy = (int)pos.Y; + if (yy < 0 || yy >= RegionInfo.RegionSizeX) + return false; + return true; } /// @@ -6526,5 +6527,21 @@ Environment.Exit(1); m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty); } + + public bool InTeleportTargetsCoolDown(UUID sourceID, UUID targetID, double timeout) + { + lock(TeleportTargetsCoolDown) + { + UUID lastSource = UUID.Zero; + TeleportTargetsCoolDown.TryGetValue(targetID, out lastSource); + if(lastSource == UUID.Zero) + { + TeleportTargetsCoolDown.Add(targetID, sourceID, timeout); + return false; + } + TeleportTargetsCoolDown.AddOrUpdate(targetID, sourceID, timeout); + return lastSource == sourceID; + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 719a5dd..402e5f7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -853,6 +853,91 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); } */ + public void ObjectTeleport(UUID sourceID, Vector3 targetPosition, Quaternion rotation, bool stop) + { + if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) + return; + + inTransit = true; + + PhysicsActor pa = RootPart.PhysActor; + if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) + { + inTransit = false; + return; + } + + if(Scene.PositionIsInCurrentRegion(targetPosition)) + { + if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) + { + inTransit = false; + return; + } + + Vector3 curPos = AbsolutePosition; + ILandObject curLand = Scene.LandChannel.GetLandObject(curPos.X, curPos.Y); + float posX = targetPosition.X; + float posY = targetPosition.Y; + ILandObject land = Scene.LandChannel.GetLandObject(posX, posY); + if(land != null && land != curLand) + { + if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) + { + inTransit = false; + return; + } + + UUID agentID; + foreach (ScenePresence av in m_sittingAvatars) + { + agentID = av.UUID; + if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) + { + inTransit = false; + return; + } + } + } + + if(stop) + RootPart.Stop(); + else + { + rotation.Normalize(); + if(Math.Abs(rotation.W) < 0.999) + { + Quaternion rot = RootPart.RotationOffset; + Vector3 vel = RootPart.Velocity; + Vector3 avel = RootPart.AngularVelocity; + Vector3 acc = RootPart.Acceleration; + + rot *= rotation; + vel *= rotation; + avel *= rotation; + acc *= rotation; + + RootPart.RotationOffset = rot; + RootPart.Velocity = vel; + RootPart.AngularVelocity = avel; + RootPart.Acceleration = acc; + } + } + + Vector3 s = RootPart.Scale * RootPart.RotationOffset; + float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; + if(targetPosition.Z < h) + targetPosition.Z = h; + + inTransit = false; + AbsolutePosition = targetPosition; + RootPart.ScheduleTerseUpdate(); + return; + } + + inTransit = false; + } + public override Vector3 Velocity { get { return RootPart.Velocity; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 6c094ee..ddf5078 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -4418,6 +4418,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public LSL_List osGetInertiaData() { + m_host.AddScriptLPS(1); + LSL_List result = new LSL_List(); float TotalMass; Vector3 CenterOfMass; @@ -4463,6 +4465,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot) { + m_host.AddScriptLPS(1); SceneObjectGroup sog = m_host.ParentGroup; if(sog== null || sog.IsDeleted) return; @@ -4499,6 +4502,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot) { + m_host.AddScriptLPS(1); + SceneObjectGroup sog = m_host.ParentGroup; if(sog== null || sog.IsDeleted) return; @@ -4538,6 +4543,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass) { + m_host.AddScriptLPS(1); SceneObjectGroup sog = m_host.ParentGroup; if(sog== null || sog.IsDeleted) return; @@ -4575,6 +4581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot) { + m_host.AddScriptLPS(1); SceneObjectGroup sog = m_host.ParentGroup; if(sog== null || sog.IsDeleted) return; @@ -4611,11 +4618,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public void osClearInertia() { + m_host.AddScriptLPS(1); SceneObjectGroup sog = m_host.ParentGroup; if(sog== null || sog.IsDeleted) return; sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero ); } + + /// + /// teleports a object (full linkset) + /// + /// the id of the linkset to teleport + /// target position + /// a rotation to apply + /// if TRUE (!=0) stop at destination + /// + /// only does teleport local to region + /// object owner must have rights to run scripts on target location + /// object owner must have rights to enter ojects on target location + /// target location parcel must have enought free prims capacity for the linkset prims + /// all avatars siting on the object must have access to target location + /// has a cool down time. retries before expire reset it + /// fail conditions are silent ignored + /// + public void osObjectTeleport(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer stop) + { + CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent"); + m_host.AddScriptLPS(1); + + UUID objUUID; + if (!UUID.TryParse(objectUUID, out objUUID)) + { + OSSLShoutError("osObjectTeleport() invalid object Key"); + return; + } + + SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID); + if(sog== null || sog.IsDeleted) + return; + + UUID myid = m_host.ParentGroup.UUID; + + sog.ObjectTeleport(myid, targetPos, rotation, stop != 0); + // a delay here may break vehicles + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index f76ff7f..4722fed 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -495,5 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot); void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass); void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot); + + void osObjectTeleport(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer stop); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 09337e5..37e7a17 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1140,5 +1140,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osClearInertia(); } + public void osObjectTeleport(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer stop) + { + m_OSSL_Functions.osObjectTeleport(objectUUID, targetPos, targetrotation, stop); + } } } -- cgit v1.1