From f69e91dc2dfe4de573093199e02e78bcdcff0e9b Mon Sep 17 00:00:00 2001
From: Melanie
Date: Mon, 16 Dec 2013 22:08:02 +0000
Subject: This is the acutal sitting avatar crossing code. This commit
implements the actual crossing mechanics for seated avatars, using the
supporting code from the previous commits. Physics is not supported yet,
although some few bits for them are already in place due to the earlier code
drops. With this commit, crossing sitting avatar by "editing" the prim across
the border, by using llSetPos or keyframe motion may already be possible.
Vehicles will come next.
---
.../Region/Framework/Scenes/SceneObjectGroup.cs | 154 ++++++++++++++++++++-
1 file changed, 152 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f16a8e6..a2e4417 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -429,6 +429,12 @@ namespace OpenSim.Region.Framework.Scenes
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
}
+ private struct avtocrossInfo
+ {
+ public ScenePresence av;
+ public uint ParentID;
+ }
+
///
/// The absolute position of this scene object in the scene
///
@@ -456,13 +462,124 @@ namespace OpenSim.Region.Framework.Scenes
|| Scene.TestBorderCross(val, Cardinals.S))
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
{
+ IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface();
+ uint x = 0;
+ uint y = 0;
+ string version = String.Empty;
+ Vector3 newpos = Vector3.Zero;
+ OpenSim.Services.Interfaces.GridRegion destination = null;
+
if (m_rootPart.KeyframeMotion != null)
m_rootPart.KeyframeMotion.StartCrossingCheck();
- m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
+ bool canCross = true;
+ foreach (ScenePresence av in m_linkedAvatars)
+ {
+ // We need to cross these agents. First, let's find
+ // out if any of them can't cross for some reason.
+ // We have to deny the crossing entirely if any
+ // of them are banned. Alternatively, we could
+ // unsit banned agents....
+
+
+ // We set the avatar position as being the object
+ // position to get the region to send to
+ if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
+ {
+ canCross = false;
+ break;
+ }
+
+ m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
+ }
+
+ if (canCross)
+ {
+ // We unparent the SP quietly so that it won't
+ // be made to stand up
+
+ List avsToCross = new List();
+
+ foreach (ScenePresence av in m_linkedAvatars)
+ {
+ avtocrossInfo avinfo = new avtocrossInfo();
+ SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
+ if (parentPart != null)
+ av.ParentUUID = parentPart.UUID;
+
+ avinfo.av = av;
+ avinfo.ParentID = av.ParentID;
+ avsToCross.Add(avinfo);
+
+ av.PrevSitOffset = av.OffsetPosition;
+ av.ParentID = 0;
+ }
+
+ // m_linkedAvatars.Clear();
+ m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
+
+ // Normalize
+ if (val.X >= Constants.RegionSize)
+ val.X -= Constants.RegionSize;
+ if (val.Y >= Constants.RegionSize)
+ val.Y -= Constants.RegionSize;
+ if (val.X < 0)
+ val.X += Constants.RegionSize;
+ if (val.Y < 0)
+ val.Y += Constants.RegionSize;
+
+ // If it's deleted, crossing was successful
+ if (IsDeleted)
+ {
+ // foreach (ScenePresence av in m_linkedAvatars)
+ foreach (avtocrossInfo avinfo in avsToCross)
+ {
+ ScenePresence av = avinfo.av;
+ if (!av.IsInTransit) // just in case...
+ {
+ m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
+
+ av.IsInTransit = true;
+
+ CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
+ d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
+ }
+ else
+ m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
+ }
+ avsToCross.Clear();
+ return;
+ }
+ else // cross failed, put avas back ??
+ {
+ foreach (avtocrossInfo avinfo in avsToCross)
+ {
+ ScenePresence av = avinfo.av;
+ av.ParentUUID = UUID.Zero;
+ av.ParentID = avinfo.ParentID;
+// m_linkedAvatars.Add(av);
+ }
+ }
+ avsToCross.Clear();
+
+ }
+ else
+ {
+ if (m_rootPart.KeyframeMotion != null)
+ m_rootPart.KeyframeMotion.CrossingFailure();
+
+ if (RootPart.PhysActor != null)
+ {
+ RootPart.PhysActor.CrossingFailure();
+ }
+ }
+ Vector3 oldp = AbsolutePosition;
+ val.X = Util.Clamp(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
+ val.Y = Util.Clamp(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
+ val.Z = Util.Clamp(oldp.Z, 0.5f, 4096.0f);
}
}
-
+
if (RootPart.GetStatusSandbox())
{
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -496,6 +613,39 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public override Vector3 Velocity
+ {
+ get { return RootPart.Velocity; }
+ set { RootPart.Velocity = value; }
+ }
+
+ private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
+ {
+ CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
+ ScenePresence agent = icon.EndInvoke(iar);
+
+ //// If the cross was successful, this agent is a child agent
+ if (agent.IsChildAgent)
+ {
+ if (agent.ParentUUID != UUID.Zero)
+ {
+ agent.ParentPart = null;
+// agent.ParentPosition = Vector3.Zero;
+// agent.ParentUUID = UUID.Zero;
+ }
+ }
+
+ agent.ParentUUID = UUID.Zero;
+// agent.Reset();
+// else // Not successful
+// agent.RestoreInCurrentScene();
+
+ // In any case
+ agent.IsInTransit = false;
+
+ m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
+ }
+
public override uint LocalId
{
get { return m_rootPart.LocalId; }
--
cgit v1.1