several changes for osTeleportObject

httptests
UbitUmarov 2017-04-15 10:46:18 +01:00
parent 156ef0bbe3
commit 0f7ffc56ce
10 changed files with 424 additions and 214 deletions

View File

@ -685,10 +685,10 @@ namespace OpenSim.Framework
ExtraData = 1 << 20, ExtraData = 1 << 20,
Sound = 1 << 21, Sound = 1 << 21,
Joint = 1 << 22, Joint = 1 << 22,
FullUpdate = 0x0fffffff, FullUpdate = 0x0fffffff,
SendInTransit = 1 << 30, SendInTransit = 0x20000000,
CancelKill = 0x4fffffff, // 1 << 31 CancelKill = 0x4fffffff, // 1 << 30
Kill = 0x80000000 // 1 << 32 Kill = 0x80000000 // 1 << 31
} }
/* included in .net 4.0 /* included in .net 4.0

View File

@ -4087,10 +4087,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
*/ */
if (entity is SceneObjectPart) if (entity is SceneObjectPart)
{ {
SceneObjectPart e = (SceneObjectPart)entity; SceneObjectPart p = (SceneObjectPart)entity;
SceneObjectGroup g = e.ParentGroup; SceneObjectGroup g = p.ParentGroup;
if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId)
return; // Don't send updates for other people's HUDs return; // Don't send updates for other people's HUDs
if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0)
{
List<uint> partIDs = (new List<uint> {p.LocalId});
lock (m_entityProps.SyncRoot)
m_entityProps.Remove(partIDs);
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Remove(partIDs);
return;
}
} }
//double priority = m_prioritizer.GetUpdatePriority(this, entity); //double priority = m_prioritizer.GetUpdatePriority(this, entity);

View File

@ -1703,11 +1703,81 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return agent; return agent;
} }
public bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx)
{
ulong regionhandler = neighbourRegion.RegionHandle;
if(agent.knowsNeighbourRegion(regionhandler))
return true;
string reason;
ulong currentRegionHandler = agent.Scene.RegionInfo.RegionHandle;
GridRegion source = new GridRegion(agent.Scene.RegionInfo);
AgentCircuitData currentAgentCircuit =
agent.Scene.AuthenticateHandler.GetAgentCircuitData(agent.ControllingClient.CircuitCode);
AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo();
agentCircuit.startpos = pos;
agentCircuit.child = true;
agentCircuit.Appearance = new AvatarAppearance();
agentCircuit.Appearance.AvatarHeight = agent.Appearance.AvatarHeight;
if (currentAgentCircuit != null)
{
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
agentCircuit.Viewer = currentAgentCircuit.Viewer;
agentCircuit.Channel = currentAgentCircuit.Channel;
agentCircuit.Mac = currentAgentCircuit.Mac;
agentCircuit.Id0 = currentAgentCircuit.Id0;
}
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath);
IPEndPoint endPoint = neighbourRegion.ExternalEndPoint;
if (Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason))
{
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
int newSizeX = neighbourRegion.RegionSizeX;
int newSizeY = neighbourRegion.RegionSizeY;
if (m_eqModule != null)
{
#region IP Translation for NAT
IClientIPEndpoint ipepClient;
if (agent.ClientView.TryGet(out ipepClient))
endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
"and EstablishAgentCommunication with seed cap {8}", LogHeader,
source.RegionName, agent.Name,
neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, newSizeX, newSizeY , capsPath);
m_eqModule.EnableSimulator(regionhandler,
endPoint, agent.UUID, newSizeX, newSizeY);
m_eqModule.EstablishAgentCommunication(agent.UUID, endPoint, capsPath,
regionhandler, newSizeX, newSizeY);
}
else
{
agent.ControllingClient.InformClientOfNeighbour(regionhandler, endPoint);
}
return true;
}
agent.RemoveNeighbourRegion(regionhandler);
return false;
}
public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx) public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx)
{ {
int ts = Util.EnvironmentTickCount(); int ts = Util.EnvironmentTickCount();
bool sucess = true;
string reason = String.Empty;
try try
{ {
AgentData cAgent = new AgentData(); AgentData cAgent = new AgentData();
agent.CopyTo(cAgent,true); agent.CopyTo(cAgent,true);
@ -1725,18 +1795,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Beyond this point, extra cleanup is needed beyond removing transit state // Beyond this point, extra cleanup is needed beyond removing transit state
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) if (sucess && !agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx))
{
sucess = false;
reason = "agent update failed";
}
if(!sucess)
{ {
// region doesn't take it // region doesn't take it
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
m_log.WarnFormat( m_log.WarnFormat(
"[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", "[ENTITY TRANSFER MODULE]: agent {0} crossing to {1} failed: {2}",
neighbourRegion.RegionName, agent.Name); agent.Name, neighbourRegion.RegionName, reason);
ReInstantiateScripts(agent); ReInstantiateScripts(agent);
if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero) if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero)
{
agent.AddToPhysicalScene(isFlying); agent.AddToPhysicalScene(isFlying);
}
return false; return false;
} }
@ -1777,7 +1855,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); Vector3 vel2 = Vector3.Zero;
if((agent.crossingFlags & 2) != 0)
vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
if (m_eqModule != null) if (m_eqModule != null)
{ {
@ -1804,7 +1884,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// this may need the attachments // this may need the attachments
agent.HasMovedAway(true); agent.HasMovedAway((agent.crossingFlags & 8) == 0);
agent.MakeChildAgent(neighbourRegion.RegionHandle); agent.MakeChildAgent(neighbourRegion.RegionHandle);
@ -2135,7 +2215,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY,
0f); 0f);
} }
#endregion
#region NotFoundLocationCache class #region NotFoundLocationCache class
// A collection of not found locations to make future lookups 'not found' lookups quick. // A collection of not found locations to make future lookups 'not found' lookups quick.

View File

@ -538,7 +538,7 @@ namespace OpenSim.Region.Framework.Scenes
public bool inTransit = false; public bool inTransit = false;
public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos); private delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos, TeleportObjectData tpData);
/// <summary> /// <summary>
/// The absolute position of this scene object in the scene /// The absolute position of this scene object in the scene
@ -560,7 +560,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
inTransit = true; inTransit = true;
SOGCrossDelegate d = CrossAsync; SOGCrossDelegate d = CrossAsync;
d.BeginInvoke(this, val, CrossAsyncCompleted, d); d.BeginInvoke(this, val, null, CrossAsyncCompleted, d);
} }
return; return;
} }
@ -601,7 +601,6 @@ namespace OpenSim.Region.Framework.Scenes
av.sitSOGmoved(); av.sitSOGmoved();
} }
// now that position is changed tell it to scripts // now that position is changed tell it to scripts
if (triggerScriptEvent) if (triggerScriptEvent)
{ {
@ -617,64 +616,75 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val) private SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val, TeleportObjectData tpdata)
{ {
Scene sogScene = sog.m_scene; Scene sogScene = sog.m_scene;
SceneObjectPart root = sog.RootPart;
bool isTeleport = tpdata != null;
if(!isTeleport)
{
if (root.DIE_AT_EDGE)
{
try
{
sogScene.DeleteSceneObject(sog, false);
}
catch (Exception)
{
m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
}
return sog;
}
if (root.RETURN_AT_EDGE)
{
// We remove the object here
try
{
List<uint> localIDs = new List<uint>();
localIDs.Add(root.LocalId);
sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
"Returned at region cross");
sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false);
}
catch (Exception)
{
m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
}
return sog;
}
}
if (root.KeyframeMotion != null)
root.KeyframeMotion.StartCrossingCheck();
if(root.PhysActor != null)
root.PhysActor.CrossingStart();
IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>(); IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>();
Vector3 newpos = Vector3.Zero;
OpenSim.Services.Interfaces.GridRegion destination = null;
if (sog.RootPart.DIE_AT_EDGE)
{
try
{
sogScene.DeleteSceneObject(sog, false);
}
catch (Exception)
{
m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
}
return sog;
}
if (sog.RootPart.RETURN_AT_EDGE)
{
// We remove the object here
try
{
List<uint> localIDs = new List<uint>();
localIDs.Add(sog.RootPart.LocalId);
sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
"Returned at region cross");
sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false);
}
catch (Exception)
{
m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
}
return sog;
}
if (sog.m_rootPart.KeyframeMotion != null)
sog.m_rootPart.KeyframeMotion.StartCrossingCheck();
if (entityTransfer == null) if (entityTransfer == null)
return sog; return sog;
Vector3 newpos = Vector3.Zero;
OpenSim.Services.Interfaces.GridRegion destination = null;
destination = entityTransfer.GetObjectDestination(sog, val, out newpos); destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
if (destination == null) if (destination == null)
return sog; return sog;
if (sog.m_sittingAvatars.Count == 0) if (sog.m_sittingAvatars.Count == 0)
{ {
entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, true); entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, !isTeleport, true);
return sog; return sog;
} }
string reason = String.Empty; string reason = String.Empty;
EntityTransferContext ctx = new EntityTransferContext(); EntityTransferContext ctx = new EntityTransferContext();
Vector3 curPos = root.GroupPosition;
foreach (ScenePresence av in sog.m_sittingAvatars) foreach (ScenePresence av in sog.m_sittingAvatars)
{ {
// We need to cross these agents. First, let's find // We need to cross these agents. First, let's find
@ -685,10 +695,15 @@ namespace OpenSim.Region.Framework.Scenes
// We set the avatar position as being the object // We set the avatar position as being the object
// position to get the region to send to // position to get the region to send to
if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) if(av.IsNPC)
{ continue;
if(av.IsInTransit)
return sog; return sog;
}
if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason))
return sog;
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
} }
@ -696,8 +711,10 @@ namespace OpenSim.Region.Framework.Scenes
// be made to stand up // be made to stand up
List<avtocrossInfo> avsToCross = new List<avtocrossInfo>(); List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
List<ScenePresence> avsToCrossFar = new List<ScenePresence>();
foreach (ScenePresence av in sog.m_sittingAvatars) ulong destHandle = destination.RegionHandle;
List<ScenePresence> sittingAvatars = GetSittingAvatars();
foreach (ScenePresence av in sittingAvatars)
{ {
byte cflags = 1; byte cflags = 1;
@ -711,68 +728,175 @@ namespace OpenSim.Region.Framework.Scenes
else else
cflags = 3; cflags = 3;
} }
if(!av.knowsNeighbourRegion(destHandle))
cflags |= 8;
// 1 is crossing // 1 is crossing
// 2 is sitting // 2 is sitting
// 4 is sitting at sittarget // 4 is sitting at sittarget
av.crossingFlags = cflags; // 8 far crossing
avinfo.av = av; avinfo.av = av;
avinfo.ParentID = av.ParentID; avinfo.ParentID = av.ParentID;
avsToCross.Add(avinfo); avsToCross.Add(avinfo);
if(!av.knowsNeighbourRegion(destHandle))
{
cflags |= 8;
avsToCrossFar.Add(av);
}
if(av.IsNPC)
av.crossingFlags = 0;
else
av.crossingFlags = cflags;
av.PrevSitOffset = av.OffsetPosition; av.PrevSitOffset = av.OffsetPosition;
av.ParentID = 0; av.ParentID = 0;
} }
Vector3 vel = root.Velocity;
Vector3 avel = root.AngularVelocity;
Vector3 acc = root.Acceleration;
Quaternion ori = root.RotationOffset;
if(isTeleport)
{
root.Stop();
sogScene.ForEachScenePresence(delegate(ScenePresence av)
{
av.ControllingClient.SendEntityUpdate(root,PrimUpdateFlags.SendInTransit);
av.ControllingClient.SendEntityTerseUpdateImmediate(root);
});
root.Velocity = tpdata.vel;
root.AngularVelocity = tpdata.avel;
root.Acceleration = tpdata.acc;
root.RotationOffset = tpdata.ori;
}
if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false)) if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false))
{ {
if(isTeleport)
{
sogScene.ForEachScenePresence(delegate(ScenePresence oav)
{
if(sittingAvatars.Contains(oav))
return;
if(oav.knowsNeighbourRegion(destHandle))
return;
oav.ControllingClient.SendEntityUpdate(root, PrimUpdateFlags.Kill);
foreach (ScenePresence sav in sittingAvatars)
{
sav.SendKillTo(oav);
}
});
}
bool crossedfar = false;
foreach (ScenePresence av in avsToCrossFar)
{
if(entityTransfer.CrossAgentCreateFarChild(av,destination, newpos, ctx))
crossedfar = true;
else
av.crossingFlags = 0;
}
if(crossedfar)
Thread.Sleep(1000);
foreach (avtocrossInfo avinfo in avsToCross) foreach (avtocrossInfo avinfo in avsToCross)
{ {
ScenePresence av = avinfo.av; ScenePresence av = avinfo.av;
if (!av.IsInTransit) // just in case... av.IsInTransit = true;
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
if(av.crossingFlags > 0)
entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, false, ctx);
if (av.IsChildAgent)
{ {
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); // avatar crossed do some extra cleanup
if (av.ParentUUID != UUID.Zero)
av.IsInTransit = true;
// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx);
if (av.IsChildAgent)
{ {
// avatar crossed do some extra cleanup av.ClearControls();
if (av.ParentUUID != UUID.Zero) av.ParentPart = null;
{
av.ClearControls();
av.ParentPart = null;
}
} }
else
{
// avatar cross failed we need do dedicated standUp
// part of it was done at CrossAgentToNewRegionAsync
// so for now just remove the sog controls
// this may need extra care
av.UnRegisterSeatControls(sog.UUID);
}
av.ParentUUID = UUID.Zero; av.ParentUUID = UUID.Zero;
av.ParentPart = null;
// In any case // In any case
av.IsInTransit = false; av.IsInTransit = false;
av.crossingFlags = 0; av.crossingFlags = 0;
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
} }
else else
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val); {
// avatar cross failed we need do dedicated standUp
// part of it was done at CrossAgentToNewRegionAsync
// so for now just remove the sog controls
// this may need extra care
av.UnRegisterSeatControls(sog.UUID);
av.ParentUUID = UUID.Zero;
av.ParentPart = null;
Vector3 oldp = curPos;
oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
av.AbsolutePosition = oldp;
av.crossingFlags = 0;
av.sitAnimation = "SIT";
av.IsInTransit = false;
if(av.Animator!= null)
av.Animator.SetMovementAnimations("STAND");
av.AddToPhysicalScene(false);
sogScene.ForEachScenePresence(delegate(ScenePresence oav)
{
if(sittingAvatars.Contains(oav))
return;
if(oav.knowsNeighbourRegion(destHandle))
av.SendAvatarDataToAgent(oav);
else
{
av.SendAvatarDataToAgent(oav);
av.SendAppearanceToAgent(oav);
if (av.Animator != null)
av.Animator.SendAnimPackToClient(oav.ControllingClient);
av.SendAttachmentsToAgentNF(oav); // not ok
}
});
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} failed.", av.Firstname, av.Lastname);
}
} }
if(crossedfar)
{
Thread.Sleep(10000);
foreach (ScenePresence av in avsToCrossFar)
{
if(av.IsChildAgent)
{
av.Scene.CloseAgent(av.UUID, false);
}
else
av.RemoveNeighbourRegion(destHandle);
}
}
avsToCrossFar.Clear();
avsToCross.Clear(); avsToCross.Clear();
sog.RemoveScriptInstances(true); sog.RemoveScriptInstances(true);
sog.Clear(); sog.Clear();
return sog; return sog;
} }
else // cross failed, put avas back ?? else
{ {
if(isTeleport)
{
if((tpdata.flags & OSTPOBJ_STOPONFAIL) == 0)
{
root.Velocity = vel;
root.AngularVelocity = avel;
root.Acceleration = acc;
}
root.RotationOffset = ori;
}
foreach (avtocrossInfo avinfo in avsToCross) foreach (avtocrossInfo avinfo in avsToCross)
{ {
ScenePresence av = avinfo.av; ScenePresence av = avinfo.av;
@ -782,7 +906,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
avsToCross.Clear(); avsToCross.Clear();
return sog; return sog;
} }
@ -794,11 +917,14 @@ namespace OpenSim.Region.Framework.Scenes
if (!sog.IsDeleted) if (!sog.IsDeleted)
{ {
SceneObjectPart rootp = sog.m_rootPart; SceneObjectPart rootp = sog.m_rootPart;
Vector3 oldp = rootp.GroupPosition; Vector3 oldp = rootp.GroupPosition;
oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
rootp.GroupPosition = oldp; rootp.GroupPosition = oldp;
rootp.Stop();
SceneObjectPart[] parts = sog.m_parts.GetArray(); SceneObjectPart[] parts = sog.m_parts.GetArray();
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
@ -812,57 +938,37 @@ namespace OpenSim.Region.Framework.Scenes
av.sitSOGmoved(); av.sitSOGmoved();
} }
sog.Velocity = Vector3.Zero;
if (sog.m_rootPart.KeyframeMotion != null) if (sog.m_rootPart.KeyframeMotion != null)
sog.m_rootPart.KeyframeMotion.CrossingFailure(); sog.m_rootPart.KeyframeMotion.CrossingFailure();
if (sog.RootPart.PhysActor != null) if (sog.RootPart.PhysActor != null)
{
sog.RootPart.PhysActor.CrossingFailure(); sog.RootPart.PhysActor.CrossingFailure();
}
sog.inTransit = false; sog.inTransit = false;
AttachToBackup();
sog.ScheduleGroupForFullUpdate(); sog.ScheduleGroupForFullUpdate();
} }
} }
/* outdated private class TeleportObjectData
private void CrossAgentToNewRegionCompleted(ScenePresence agent)
{ {
//// If the cross was successful, this agent is a child agent public int flags;
if (agent.IsChildAgent) public Vector3 vel;
{ public Vector3 avel;
if (agent.ParentUUID != UUID.Zero) public Vector3 acc;
{ public Quaternion ori;
agent.HandleForceReleaseControls(agent.ControllingClient,agent.UUID); public UUID sourceID;
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);
} }
*/
// copy from LSL_constants.cs // copy from LSL_constants.cs
const int OSTPOBJ_STOPATTARRGET = 0x1; // stops at destination const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination
const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails
const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation
public void TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags) public int TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags)
{ {
if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null)
return; return -1;
inTransit = true; inTransit = true;
@ -870,7 +976,41 @@ namespace OpenSim.Region.Framework.Scenes
if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/)
{ {
inTransit = false; inTransit = false;
return; return -1;
}
bool stop = (flags & OSTPOBJ_STOPATTARGET) != 0;
bool setrot = (flags & OSTPOBJ_SETROT) != 0;
rotation.Normalize();
Quaternion currentRot = RootPart.RotationOffset;
if(setrot)
rotation = Quaternion.Conjugate(currentRot) * rotation;
bool dorot = setrot | (Math.Abs(rotation.W) < 0.99999);
Vector3 vel = Vector3.Zero;
Vector3 avel = Vector3.Zero;
Vector3 acc = Vector3.Zero;
if(!stop)
{
vel = RootPart.Velocity;
avel = RootPart.AngularVelocity;
acc = RootPart.Acceleration;
}
Quaternion ori = RootPart.RotationOffset;
if(dorot)
{
if(!stop)
{
vel *= rotation;
avel *= rotation;
acc *= rotation;
}
ori *= rotation;
} }
if(Scene.PositionIsInCurrentRegion(targetPosition)) if(Scene.PositionIsInCurrentRegion(targetPosition))
@ -878,7 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes
if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0))
{ {
inTransit = false; inTransit = false;
return; return -2;
} }
Vector3 curPos = AbsolutePosition; Vector3 curPos = AbsolutePosition;
@ -891,7 +1031,7 @@ namespace OpenSim.Region.Framework.Scenes
if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) if(!Scene.Permissions.CanObjectEnterWithScripts(this, land))
{ {
inTransit = false; inTransit = false;
return; return -3;
} }
UUID agentID; UUID agentID;
@ -901,49 +1041,15 @@ namespace OpenSim.Region.Framework.Scenes
if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID))
{ {
inTransit = false; inTransit = false;
return; return -4;
} }
} }
} }
bool stop = (flags & OSTPOBJ_STOPATTARRGET) != 0; RootPart.Velocity = vel;
bool setrot = (flags & OSTPOBJ_SETROT) != 0; RootPart.AngularVelocity = avel;
RootPart.Acceleration = acc;
rotation.Normalize(); RootPart.RotationOffset = ori;
Quaternion currentRot = RootPart.RotationOffset;
if(setrot)
rotation = Quaternion.Conjugate(currentRot) * rotation;
bool dorot = setrot | (Math.Abs(rotation.W) < 0.999);
if(stop)
{
RootPart.Stop();
}
else
{
if(dorot)
{
Vector3 vel = RootPart.Velocity;
Vector3 avel = RootPart.AngularVelocity;
Vector3 acc = RootPart.Acceleration;
vel *= rotation;
avel *= rotation;
acc *= rotation;
RootPart.Velocity = vel;
RootPart.AngularVelocity = avel;
RootPart.Acceleration = acc;
}
}
if(dorot)
{
currentRot *= rotation;
RootPart.RotationOffset = currentRot;
}
Vector3 s = RootPart.Scale * RootPart.RotationOffset; Vector3 s = RootPart.Scale * RootPart.RotationOffset;
float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f;
@ -953,10 +1059,27 @@ namespace OpenSim.Region.Framework.Scenes
inTransit = false; inTransit = false;
AbsolutePosition = targetPosition; AbsolutePosition = targetPosition;
RootPart.ScheduleTerseUpdate(); RootPart.ScheduleTerseUpdate();
return; return 1;
} }
inTransit = false; if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 20.0))
{
inTransit = false;
return -1;
}
TeleportObjectData tdata = new TeleportObjectData();
tdata.flags = flags;
tdata.vel = vel;
tdata.avel = avel;
tdata.acc = acc;
tdata.ori = ori;
tdata.sourceID = sourceID;
SOGCrossDelegate d = CrossAsync;
d.BeginInvoke(this, targetPosition, tdata, CrossAsyncCompleted, d);
return 0;
} }
public override Vector3 Velocity public override Vector3 Velocity
@ -5398,9 +5521,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (avs[i].Name == name) if (avs[i].Name == name)
{ {
GetLinkNumber_lastname = name; GetLinkNumber_lastname = name;
GetLinkNumber_lastnumber = j; GetLinkNumber_lastnumber = j;
return j; return j;
} }
} }
} }

View File

@ -1066,7 +1066,7 @@ namespace OpenSim.Region.Framework.Scenes
m_angularVelocity = value; m_angularVelocity = value;
PhysicsActor actor = PhysActor; PhysicsActor actor = PhysActor;
if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
{ {
actor.RotationalVelocity = m_angularVelocity; actor.RotationalVelocity = m_angularVelocity;
} }
@ -1092,6 +1092,12 @@ namespace OpenSim.Region.Framework.Scenes
m_acceleration = Vector3.Zero; m_acceleration = Vector3.Zero;
else else
m_acceleration = value; m_acceleration = value;
PhysicsActor actor = PhysActor;
if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
{
actor.Acceleration = m_acceleration;
}
} }
} }
@ -2016,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes
// SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
public void SetVelocity(Vector3 pVel, bool localGlobalTF) public void SetVelocity(Vector3 pVel, bool localGlobalTF)
{ {
if (ParentGroup == null || ParentGroup.IsDeleted) if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
return; return;
if (ParentGroup.IsAttachment) if (ParentGroup.IsAttachment)
@ -2043,7 +2049,7 @@ namespace OpenSim.Region.Framework.Scenes
// SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF) public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
{ {
if (ParentGroup == null || ParentGroup.IsDeleted) if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
return; return;
if (ParentGroup.IsAttachment) if (ParentGroup.IsAttachment)
@ -2077,6 +2083,9 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="localGlobalTF">true for the local frame, false for the global frame</param> /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF) public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF)
{ {
if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
return;
Vector3 impulse = impulsei; Vector3 impulse = impulsei;
if (localGlobalTF) if (localGlobalTF)
@ -3376,25 +3385,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void SendFullUpdateToClient(IClientAPI remoteClient) public void SendFullUpdateToClient(IClientAPI remoteClient)
{ {
SendFullUpdateToClient(remoteClient, OffsetPosition); if (ParentGroup == null || ParentGroup.IsDeleted)
}
/// <summary>
/// Sends a full update to the client
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="lPos"></param>
public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos)
{
if (ParentGroup == null)
return;
// Suppress full updates during attachment editing
// sl Does send them
// if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
// return;
if (ParentGroup.IsDeleted)
return; return;
if (ParentGroup.IsAttachment if (ParentGroup.IsAttachment

View File

@ -85,7 +85,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private Vector3 m_lastposition; private Vector3 m_lastposition;
private Vector3 m_rotationalVelocity; private Vector3 m_rotationalVelocity;
private Vector3 _size; private Vector3 _size;
private Vector3 _acceleration; private Vector3 m_acceleration;
private IntPtr Amotor; private IntPtr Amotor;
internal Vector3 m_force; internal Vector3 m_force;
@ -746,8 +746,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public override Vector3 Acceleration public override Vector3 Acceleration
{ {
get { return _acceleration; } get { return m_acceleration; }
set { } set
{
if(m_outbounds)
m_acceleration = value;
}
} }
public override Vector3 RotationalVelocity public override Vector3 RotationalVelocity
@ -767,7 +771,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
if (value.IsFinite()) if (value.IsFinite())
{ {
AddChange(changes.AngVelocity, value); if(m_outbounds)
m_rotationalVelocity = value;
else
AddChange(changes.AngVelocity, value);
} }
else else
{ {
@ -941,7 +948,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
} }
public void SetAcceleration(Vector3 accel) public void SetAcceleration(Vector3 accel)
{ {
_acceleration = accel; m_acceleration = accel;
} }
public override void AddForce(Vector3 force, bool pushforce) public override void AddForce(Vector3 force, bool pushforce)
@ -2748,7 +2755,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_angularForceacc = Vector3.Zero; m_angularForceacc = Vector3.Zero;
// m_torque = Vector3.Zero; // m_torque = Vector3.Zero;
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
_acceleration = Vector3.Zero; m_acceleration = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero; m_rotationalVelocity = Vector3.Zero;
_target_velocity = Vector3.Zero; _target_velocity = Vector3.Zero;
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
@ -3784,9 +3791,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_outbounds = true; m_outbounds = true;
lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
_acceleration.X = 0; m_acceleration.X = 0;
_acceleration.Y = 0; m_acceleration.Y = 0;
_acceleration.Z = 0; m_acceleration.Z = 0;
_velocity.X = 0; _velocity.X = 0;
_velocity.Y = 0; _velocity.Y = 0;
@ -3915,12 +3922,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_orientation.W = ori.W; _orientation.W = ori.W;
} }
// update velocities and aceleration // update velocities and acceleration
if (_zeroFlag || lastZeroFlag) if (_zeroFlag || lastZeroFlag)
{ {
// disable interpolators // disable interpolators
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
_acceleration = Vector3.Zero; m_acceleration = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero; m_rotationalVelocity = Vector3.Zero;
} }
else else
@ -3929,7 +3936,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
d.Vector3 vel = d.BodyGetLinearVel(Body); d.Vector3 vel = d.BodyGetLinearVel(Body);
_acceleration = _velocity; m_acceleration = _velocity;
if ((Math.Abs(vel.X) < 0.005f) && if ((Math.Abs(vel.X) < 0.005f) &&
(Math.Abs(vel.Y) < 0.005f) && (Math.Abs(vel.Y) < 0.005f) &&
@ -3937,21 +3944,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
float t = -m_invTimeStep; float t = -m_invTimeStep;
_acceleration = _acceleration * t; m_acceleration = m_acceleration * t;
} }
else else
{ {
_velocity.X = vel.X; _velocity.X = vel.X;
_velocity.Y = vel.Y; _velocity.Y = vel.Y;
_velocity.Z = vel.Z; _velocity.Z = vel.Z;
_acceleration = (_velocity - _acceleration) * m_invTimeStep; m_acceleration = (_velocity - m_acceleration) * m_invTimeStep;
} }
if ((Math.Abs(_acceleration.X) < 0.01f) && if ((Math.Abs(m_acceleration.X) < 0.01f) &&
(Math.Abs(_acceleration.Y) < 0.01f) && (Math.Abs(m_acceleration.Y) < 0.01f) &&
(Math.Abs(_acceleration.Z) < 0.01f)) (Math.Abs(m_acceleration.Z) < 0.01f))
{ {
_acceleration = Vector3.Zero; m_acceleration = Vector3.Zero;
} }
vel = d.BodyGetAngularVel(Body); vel = d.BodyGetAngularVel(Body);

View File

@ -4664,7 +4664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// has a cool down time. retries before expire reset it /// has a cool down time. retries before expire reset it
/// fail conditions are silent ignored /// fail conditions are silent ignored
/// </remarks> /// </remarks>
public void osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags) public LSL_Integer osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags)
{ {
CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject"); CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject");
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
@ -4673,16 +4673,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!UUID.TryParse(objectUUID, out objUUID)) if (!UUID.TryParse(objectUUID, out objUUID))
{ {
OSSLShoutError("osTeleportObject() invalid object Key"); OSSLShoutError("osTeleportObject() invalid object Key");
return; return -1;
} }
SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID); SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID);
if(sog== null || sog.IsDeleted) if(sog== null || sog.IsDeleted)
return; return -1;
UUID myid = m_host.ParentGroup.UUID; UUID myid = m_host.ParentGroup.UUID;
sog.TeleportObject(myid, targetPos, rotation, flags); return sog.TeleportObject(myid, targetPos, rotation, flags);
// a delay here may break vehicles // a delay here may break vehicles
} }

View File

@ -51,7 +51,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
/// </summary> /// </summary>
public enum ThreatLevel public enum ThreatLevel
{ {
// Not documented, presumably means permanently disabled ?
NoAccess = -1, NoAccess = -1,
/// <summary> /// <summary>
@ -496,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass); 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 osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot);
void osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags); LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags);
LSL_Integer osGetLinkNumber(LSL_String name); LSL_Integer osGetLinkNumber(LSL_String name);
} }
} }

View File

@ -856,7 +856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
// for osTeleportObject // for osTeleportObject
public const int OSTPOBJ_NONE = 0x0; public const int OSTPOBJ_NONE = 0x0;
public const int OSTPOBJ_STOPATTARRGET = 0x1; // stops at destination public const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination
public const int OSTPOBJ_STOPONFAIL = 0x2; // stops at jump point if tp fails public const int OSTPOBJ_STOPONFAIL = 0x2; // stops at jump point if tp fails
public const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation public const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation

View File

@ -1140,9 +1140,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_OSSL_Functions.osClearInertia(); m_OSSL_Functions.osClearInertia();
} }
public void osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags) public LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags)
{ {
m_OSSL_Functions.osTeleportObject(objectUUID, targetPos, targetrotation, flags); return m_OSSL_Functions.osTeleportObject(objectUUID, targetPos, targetrotation, flags);
} }
public LSL_Integer osGetLinkNumber(LSL_String name) public LSL_Integer osGetLinkNumber(LSL_String name)