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.master-beforevarregion
parent
82ebb86d58
commit
f69e91dc2d
|
@ -429,6 +429,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
|
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct avtocrossInfo
|
||||||
|
{
|
||||||
|
public ScenePresence av;
|
||||||
|
public uint ParentID;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute position of this scene object in the scene
|
/// The absolute position of this scene object in the scene
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -456,10 +462,121 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|| Scene.TestBorderCross(val, Cardinals.S))
|
|| Scene.TestBorderCross(val, Cardinals.S))
|
||||||
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
||||||
{
|
{
|
||||||
|
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
||||||
|
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)
|
if (m_rootPart.KeyframeMotion != null)
|
||||||
m_rootPart.KeyframeMotion.StartCrossingCheck();
|
m_rootPart.KeyframeMotion.StartCrossingCheck();
|
||||||
|
|
||||||
|
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<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
|
||||||
|
|
||||||
|
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);
|
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<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||||
|
val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||||
|
val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
public override uint LocalId
|
||||||
{
|
{
|
||||||
get { return m_rootPart.LocalId; }
|
get { return m_rootPart.LocalId; }
|
||||||
|
|
Loading…
Reference in New Issue