Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
commit
8bc43ea773
|
@ -561,16 +561,15 @@ namespace OpenSim.Framework
|
|||
if (attachpoint == 0)
|
||||
return false;
|
||||
|
||||
if (item == UUID.Zero)
|
||||
{
|
||||
lock (m_attachments)
|
||||
{
|
||||
if (item == UUID.Zero)
|
||||
{
|
||||
if (m_attachments.ContainsKey(attachpoint))
|
||||
{
|
||||
m_attachments.Remove(attachpoint);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -582,13 +581,27 @@ namespace OpenSim.Framework
|
|||
//
|
||||
// Therefore, we will carry on with the set if the existing attachment has no asset id.
|
||||
AvatarAttachment existingAttachment = GetAttachmentForItem(item);
|
||||
if (existingAttachment != null
|
||||
&& existingAttachment.AssetID != UUID.Zero
|
||||
&& existingAttachment.AttachPoint == (attachpoint & 0x7F))
|
||||
if (existingAttachment != null)
|
||||
{
|
||||
// m_log.DebugFormat("[AVATAR APPEARANCE] attempt to attach an already attached item {0}",item);
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARANCE]: Found existing attachment for {0}, asset {1} at point {2}",
|
||||
// existingAttachment.ItemID, existingAttachment.AssetID, existingAttachment.AttachPoint);
|
||||
|
||||
if (existingAttachment.AssetID != UUID.Zero && existingAttachment.AttachPoint == (attachpoint & 0x7F))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AVATAR APPEARANCE]: Ignoring attempt to attach an already attached item {0} at point {1}",
|
||||
item, attachpoint);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove it here so that the later append does not add a second attachment but we still update
|
||||
// the assetID
|
||||
DetachAttachment(existingAttachment.ItemID);
|
||||
}
|
||||
}
|
||||
|
||||
// check if this is an append or a replace, 0x80 marks it as an append
|
||||
if ((attachpoint & 0x80) > 0)
|
||||
|
@ -601,6 +614,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -648,6 +662,10 @@ namespace OpenSim.Framework
|
|||
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
||||
if (index >= 0)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}",
|
||||
// m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint);
|
||||
|
||||
// Remove it from the list of attachments at that attach point
|
||||
m_attachments[kvp.Key].RemoveAt(index);
|
||||
|
||||
|
|
|
@ -359,8 +359,9 @@ Asset service request failures: {3}" + Environment.NewLine,
|
|||
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
|
||||
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
|
||||
|
||||
/* 20130319 RA: For the moment, disable the dump of 'scene' catagory as they are mostly output by
|
||||
* the two formatted printouts above.
|
||||
SortedDictionary<string, SortedDictionary<string, Stat>> sceneStats;
|
||||
|
||||
if (StatsManager.TryGetStats("scene", out sceneStats))
|
||||
{
|
||||
foreach (KeyValuePair<string, SortedDictionary<string, Stat>> kvp in sceneStats)
|
||||
|
@ -374,6 +375,7 @@ Asset service request failures: {3}" + Environment.NewLine,
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
sb.Append(Environment.NewLine);
|
||||
|
|
|
@ -369,8 +369,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
AssetBase asset = null;
|
||||
|
||||
string filename = GetFileName(id);
|
||||
|
||||
if (File.Exists(filename))
|
||||
while (File.Exists(filename))
|
||||
{
|
||||
FileStream stream = null;
|
||||
try
|
||||
|
@ -381,6 +380,8 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
asset = (AssetBase)bformatter.Deserialize(stream);
|
||||
|
||||
m_DiskHits++;
|
||||
|
||||
break;
|
||||
}
|
||||
catch (System.Runtime.Serialization.SerializationException e)
|
||||
{
|
||||
|
@ -393,12 +394,24 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
// {different version of AssetBase} -- we should attempt to
|
||||
// delete it and re-cache
|
||||
File.Delete(filename);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// This is a sharing violation: File exists but can't be opened because it's
|
||||
// being written
|
||||
Thread.Sleep(100);
|
||||
|
||||
continue;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||
filename, id, e.Message, e.StackTrace);
|
||||
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -573,8 +573,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}",
|
||||
// so.Name, so.LocalId, sp.Name, m_scene.Name);
|
||||
// "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}",
|
||||
// so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name);
|
||||
|
||||
// Scripts MUST be snapshotted before the object is
|
||||
// removed from the scene because doing otherwise will
|
||||
|
|
|
@ -829,7 +829,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
|||
sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
|
||||
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
|
||||
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
|
||||
TestClient tc = new TestClient(acd, sceneA, sh.SceneManager);
|
||||
List<TestClient> destinationTestClients = new List<TestClient>();
|
||||
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
|
||||
|
||||
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager);
|
||||
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
|
||||
|
||||
InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
@ -848,7 +854,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
|||
teleportLookAt,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
|
||||
((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide();
|
||||
destinationTestClients[0].CompleteMovement();
|
||||
|
||||
// Check attachments have made it into sceneB
|
||||
ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
|
||||
|
|
|
@ -361,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
|
||||
public void QueueAppearanceSave(UUID agentid)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
|
||||
|
||||
// 10000 ticks per millisecond, 1000 milliseconds per second
|
||||
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
|
||||
|
@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
return;
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
|
||||
|
||||
// This could take awhile since it needs to pull inventory
|
||||
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
|
||||
|
@ -667,6 +667,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
// multiple save requests.
|
||||
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||
|
||||
// List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
|
||||
// foreach (AvatarAttachment att in attachments)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: For {0} saving attachment {1} at point {2}",
|
||||
// sp.Name, att.ItemID, att.AttachPoint);
|
||||
// }
|
||||
|
||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||
|
||||
// Trigger this here because it's the final step in the set/queue/save process for appearance setting.
|
||||
|
|
|
@ -256,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
|||
// If camera is moved into client, then camera position can be used
|
||||
// MT: No, it can't, as chat is heard from the avatar position, not
|
||||
// the camera position.
|
||||
s.ForEachRootScenePresence(
|
||||
s.ForEachScenePresence(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
if (destination != UUID.Zero && presence.UUID != destination)
|
||||
|
|
|
@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
if (!DisableInterRegionTeleportCancellation)
|
||||
client.OnTeleportCancel += OnClientCancelTeleport;
|
||||
|
||||
client.OnConnectionClosed += OnConnectionClosed;
|
||||
}
|
||||
|
||||
public virtual void Close() {}
|
||||
|
@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
#region Agent Teleports
|
||||
|
||||
private void OnConnectionClosed(IClientAPI client)
|
||||
{
|
||||
if (client.IsLoggingOut)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
|
||||
client.Name, Scene.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientCancelTeleport(IClientAPI client)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
|
||||
|
@ -520,12 +534,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
|
||||
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
|
||||
|
||||
// if (!sp.ValidateAttachments())
|
||||
// {
|
||||
// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
|
||||
// return;
|
||||
// }
|
||||
|
||||
string reason;
|
||||
string version;
|
||||
if (!Scene.SimulationService.QueryAccess(
|
||||
|
@ -588,6 +596,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
|
||||
// Let's create an agent there if one doesn't exist yet.
|
||||
// NOTE: logout will always be false for a non-HG teleport.
|
||||
bool logout = false;
|
||||
if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
|
||||
{
|
||||
|
@ -608,6 +617,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
return;
|
||||
}
|
||||
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Past this point we have to attempt clean up if the teleport fails, so update transfer state.
|
||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
|
||||
|
@ -630,11 +647,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
if (m_eqModule != null)
|
||||
{
|
||||
// The EnableSimulator message makes the client establish a connection with the destination
|
||||
// simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
|
||||
// correct circuit code.
|
||||
m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID);
|
||||
|
||||
// ES makes the client send a UseCircuitCode message to the destination,
|
||||
// which triggers a bunch of things there.
|
||||
// So let's wait
|
||||
// XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
|
||||
// simulator to confirm that it has established communication with the viewer.
|
||||
Thread.Sleep(200);
|
||||
|
||||
// At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
|
||||
|
@ -645,6 +664,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
else
|
||||
{
|
||||
// XXX: This is a little misleading since we're information the client of its avatar destination,
|
||||
// which may or may not be a neighbour region of the source region. This path is probably little
|
||||
// used anyway (with EQ being the one used). But it is currently being used for test code.
|
||||
sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
|
||||
}
|
||||
}
|
||||
|
@ -662,14 +684,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
|
||||
|
||||
// We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
|
||||
// establish th econnection to the destination which makes it return true.
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// A common teleport failure occurs when we can send CreateAgent to the
|
||||
// destination region but the viewer cannot establish the connection (e.g. due to network issues between
|
||||
// the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
|
||||
// there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
|
||||
if (!UpdateAgent(reg, finalDestination, agent, sp))
|
||||
{
|
||||
// Region doesn't take it
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.",
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
|
||||
Fail(sp, finalDestination, logout);
|
||||
Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -679,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
CleanupAbortedInterRegionTeleport(sp, finalDestination);
|
||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -688,6 +733,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
|
||||
capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
|
||||
|
||||
// We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
|
||||
// where that neighbour simulator could otherwise request a child agent create on the source which then
|
||||
// closes our existing agent which is still signalled as root.
|
||||
sp.IsChildAgent = true;
|
||||
|
||||
if (m_eqModule != null)
|
||||
{
|
||||
m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
|
||||
|
@ -698,19 +748,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
teleportFlags, capsPath);
|
||||
}
|
||||
|
||||
// Let's set this to true tentatively. This does not trigger OnChildAgent
|
||||
sp.IsChildAgent = true;
|
||||
|
||||
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
||||
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
|
||||
// that the client contacted the destination before we close things here.
|
||||
if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
|
||||
{
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
|
||||
Fail(sp, finalDestination, logout);
|
||||
Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -733,8 +789,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// Now let's make it officially a child agent
|
||||
sp.MakeChildAgent();
|
||||
|
||||
// sp.Scene.CleanDroppedAttachments();
|
||||
|
||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||
|
||||
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||
|
@ -774,7 +828,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// <remarks>
|
||||
/// <param name='sp'> </param>
|
||||
/// <param name='finalDestination'></param>
|
||||
protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
|
||||
protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||
|
||||
|
@ -793,12 +847,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// <param name='sp'></param>
|
||||
/// <param name='finalDestination'></param>
|
||||
/// <param name='logout'></param>
|
||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
|
||||
/// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
|
||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
|
||||
{
|
||||
CleanupAbortedInterRegionTeleport(sp, finalDestination);
|
||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
||||
|
||||
sp.ControllingClient.SendTeleportFailed(
|
||||
string.Format("Problems connecting to destination {0}", finalDestination.RegionName));
|
||||
string.Format(
|
||||
"Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason));
|
||||
|
||||
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// This is a state machine.
|
||||
///
|
||||
/// [Entry] => Preparing
|
||||
/// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] }
|
||||
/// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp }
|
||||
/// Cancelling => CleaningUp
|
||||
/// ReceivedAtDestination => CleaningUp
|
||||
/// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
|
||||
/// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
|
||||
/// Cancelling => CleaningUp || Aborting
|
||||
/// ReceivedAtDestination => CleaningUp || Aborting
|
||||
/// CleaningUp => [Exit]
|
||||
/// Aborting => [Exit]
|
||||
///
|
||||
/// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
|
||||
/// However, any state can transition to CleaningUp if the teleport has failed.
|
||||
|
@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
Transferring, // The agent is in the process of being transferred to a destination
|
||||
ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
|
||||
CleaningUp, // The agent is being changed to child/removed after a transfer
|
||||
Cancelling // The user has cancelled the teleport but we have yet to act upon this.
|
||||
Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
|
||||
Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// Illegal to try and update an agent that's not actually in transit.
|
||||
if (!m_agentsInTransit.ContainsKey(id))
|
||||
{
|
||||
if (newState != AgentTransferState.Cancelling)
|
||||
if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
|
||||
failureMessage = string.Format(
|
||||
"Agent with ID {0} is not registered as in transit in {1}",
|
||||
id, m_mod.Scene.RegionInfo.RegionName);
|
||||
|
@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
{
|
||||
oldState = m_agentsInTransit[id];
|
||||
|
||||
if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||
if (newState == AgentTransferState.Aborting)
|
||||
{
|
||||
transitionOkay = true;
|
||||
}
|
||||
else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||
{
|
||||
transitionOkay = true;
|
||||
}
|
||||
|
@ -292,8 +298,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
// There should be no race condition here since no other code should be removing the agent transfer or
|
||||
// changing the state to another other than Transferring => ReceivedAtDestination.
|
||||
while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0)
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (m_agentsInTransit[id] == AgentTransferState.ReceivedAtDestination)
|
||||
break;
|
||||
}
|
||||
|
||||
// m_log.Debug(" >>> Waiting... " + count);
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
|
|||
{
|
||||
lock (m_logFileWriteLock)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
DateTime now = DateTime.UtcNow;
|
||||
if (m_logFile == null || now > m_logFileEndTime)
|
||||
{
|
||||
if (m_logFile != null)
|
||||
|
|
|
@ -2990,8 +2990,22 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
sp.IsChildAgent = false;
|
||||
sp.IsLoggingIn = true;
|
||||
|
||||
// We leave a 5 second pause before attempting to rez attachments to avoid a clash with
|
||||
// version 3 viewers that maybe doing their own attachment rezzing related to their current
|
||||
// outfit folder on startup. If these operations do clash, then the symptoms are invisible
|
||||
// attachments until one zooms in on the avatar.
|
||||
//
|
||||
// We do not pause if we are launching on the same thread anyway in order to avoid pointlessly
|
||||
// delaying any attachment related regression tests.
|
||||
if (AttachmentsModule != null)
|
||||
Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
|
||||
Util.FireAndForget(
|
||||
o =>
|
||||
{
|
||||
if (Util.FireAndForgetMethod != FireAndForgetMethod.None)
|
||||
Thread.Sleep(5000);
|
||||
|
||||
AttachmentsModule.RezAttachments(sp);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1529,6 +1529,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
}
|
||||
|
||||
// XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
|
||||
// If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work.
|
||||
// This may be due to viewer code or it may be something we're not doing properly simulator side.
|
||||
lock (m_attachments)
|
||||
{
|
||||
foreach (SceneObjectGroup sog in m_attachments)
|
||||
sog.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
|
||||
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
|
||||
|
|
|
@ -94,7 +94,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
// SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, eqmA);
|
||||
SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
|
||||
|
||||
ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
TestClient tc = new TestClient(acd, sceneA, sh.SceneManager);
|
||||
List<TestClient> destinationTestClients = new List<TestClient>();
|
||||
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
|
||||
|
||||
ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager);
|
||||
originalSp.AbsolutePosition = new Vector3(128, 32, 10);
|
||||
|
||||
// originalSp.Flying = true;
|
||||
|
|
|
@ -26,7 +26,10 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
|
@ -40,8 +43,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
|||
using OpenSim.Region.CoreModules.World.Permissions;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
{
|
||||
|
@ -68,7 +69,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TestSameRegionTeleport()
|
||||
public void TestSameRegion()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
@ -106,10 +107,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TestSameSimulatorSeparatedRegionsTeleport()
|
||||
public void TestSameSimulatorIsolatedRegions()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
|
@ -141,9 +142,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
|
||||
sp.AbsolutePosition = new Vector3(30, 31, 32);
|
||||
|
||||
// XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
|
||||
// UDP stack (?)
|
||||
// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB;
|
||||
List<TestClient> destinationTestClients = new List<TestClient>();
|
||||
EntityTransferHelpers.SetUpInformClientOfNeighbour((TestClient)sp.ControllingClient, destinationTestClients);
|
||||
|
||||
sceneA.RequestTeleportLocation(
|
||||
sp.ControllingClient,
|
||||
|
@ -152,7 +152,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
teleportLookAt,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
|
||||
((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
|
||||
// SetupInformClientOfNeighbour() will have handled the callback into the target scene to setup the child
|
||||
// agent. This call will now complete the movement of the user into the destination and upgrade the agent
|
||||
// from child to root.
|
||||
destinationTestClients[0].CompleteMovement();
|
||||
|
||||
Assert.That(sceneA.GetScenePresence(userId), Is.Null);
|
||||
|
||||
|
@ -177,7 +180,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
/// Test teleport procedures when the target simulator returns false when queried about access.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSameSimulatorSeparatedRegionsQueryAccessFails()
|
||||
public void TestSameSimulatorIsolatedRegions_DeniedOnQueryAccess()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
@ -261,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
/// Test teleport procedures when the target simulator create agent step is refused.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSameSimulatorSeparatedRegionsCreateAgentFails()
|
||||
public void TestSameSimulatorIsolatedRegions_DeniedOnCreateAgent()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
@ -333,12 +336,100 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test teleport when the destination region does not process (or does not receive) the connection attempt
|
||||
/// from the viewer.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This could be quite a common case where the source region can connect to a remove destination region
|
||||
/// (for CreateAgent) but the viewer cannot reach the destination region due to network issues.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
public void TestSameSimulatorNeighbouringRegionsTeleport()
|
||||
public void TestSameSimulatorIsolatedRegions_DestinationDidNotProcessViewerConnection()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
Vector3 preTeleportPosition = new Vector3(30, 31, 32);
|
||||
|
||||
EntityTransferModule etmA = new EntityTransferModule();
|
||||
EntityTransferModule etmB = new EntityTransferModule();
|
||||
|
||||
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("EntityTransferModule", etmA.Name);
|
||||
config.Configs["Modules"].Set("SimulationServices", lscm.Name);
|
||||
|
||||
config.AddConfig("EntityTransfer");
|
||||
|
||||
// In order to run a single threaded regression test we do not want the entity transfer module waiting
|
||||
// for a callback from the destination scene before removing its avatar data.
|
||||
config.Configs["EntityTransfer"].Set("wait_for_callback", false);
|
||||
|
||||
// config.AddConfig("Startup");
|
||||
// config.Configs["Startup"].Set("serverside_object_permissions", true);
|
||||
|
||||
SceneHelpers sh = new SceneHelpers();
|
||||
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
|
||||
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
|
||||
|
||||
SceneHelpers.SetupSceneModules(sceneA, config, etmA );
|
||||
|
||||
// We need to set up the permisions module on scene B so that our later use of agent limit to deny
|
||||
// QueryAccess won't succeed anyway because administrators are always allowed in and the default
|
||||
// IsAdministrator if no permissions module is present is true.
|
||||
SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB });
|
||||
|
||||
// Shared scene modules
|
||||
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
|
||||
|
||||
Vector3 teleportPosition = new Vector3(10, 11, 12);
|
||||
Vector3 teleportLookAt = new Vector3(20, 21, 22);
|
||||
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
|
||||
sp.AbsolutePosition = preTeleportPosition;
|
||||
|
||||
sceneA.RequestTeleportLocation(
|
||||
sp.ControllingClient,
|
||||
sceneB.RegionInfo.RegionHandle,
|
||||
teleportPosition,
|
||||
teleportLookAt,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
|
||||
// FIXME: Not setting up InformClientOfNeighbour on the TestClient means that it does not initiate
|
||||
// communication with the destination region. But this is a very non-obvious way of doing it - really we
|
||||
// should be forced to expicitly set this up.
|
||||
|
||||
Assert.That(sceneB.GetScenePresence(userId), Is.Null);
|
||||
|
||||
ScenePresence sceneASp = sceneA.GetScenePresence(userId);
|
||||
Assert.That(sceneASp, Is.Not.Null);
|
||||
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
|
||||
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
|
||||
|
||||
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// TODO: Add assertions to check correct circuit details in both scenes.
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
// position instead).
|
||||
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
|
||||
|
||||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSameSimulatorNeighbouringRegions()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
TestHelpers.EnableLogging();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
EntityTransferModule etmA = new EntityTransferModule();
|
||||
|
@ -366,10 +457,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Vector3 teleportPosition = new Vector3(10, 11, 12);
|
||||
Vector3 teleportLookAt = new Vector3(20, 21, 22);
|
||||
|
||||
ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
|
||||
originalSp.AbsolutePosition = new Vector3(30, 31, 32);
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
TestClient tc = new TestClient(acd, sceneA, sh.SceneManager);
|
||||
List<TestClient> destinationTestClients = new List<TestClient>();
|
||||
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
|
||||
|
||||
ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager);
|
||||
beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32);
|
||||
|
||||
ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId);
|
||||
Assert.That(beforeSceneASp, Is.Not.Null);
|
||||
Assert.That(beforeSceneASp.IsChildAgent, Is.False);
|
||||
|
||||
|
@ -377,10 +472,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(beforeSceneBSp, Is.Not.Null);
|
||||
Assert.That(beforeSceneBSp.IsChildAgent, Is.True);
|
||||
|
||||
// XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
|
||||
// UDP stack (?)
|
||||
// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB;
|
||||
|
||||
// In this case, we will not receieve a second InformClientOfNeighbour since the viewer already knows
|
||||
// about the neighbour region it is teleporting to.
|
||||
sceneA.RequestTeleportLocation(
|
||||
beforeSceneASp.ControllingClient,
|
||||
sceneB.RegionInfo.RegionHandle,
|
||||
|
@ -388,7 +481,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
teleportLookAt,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
|
||||
((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide();
|
||||
destinationTestClients[0].CompleteMovement();
|
||||
|
||||
ScenePresence afterSceneASp = sceneA.GetScenePresence(userId);
|
||||
Assert.That(afterSceneASp, Is.Not.Null);
|
||||
|
|
|
@ -176,16 +176,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n",
|
||||
// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID,
|
||||
// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos);
|
||||
ct.Rows.Add(
|
||||
new ConsoleDisplayTableRow(
|
||||
new List<string>()
|
||||
{
|
||||
|
||||
ct.AddRow(
|
||||
attachmentObject.Name,
|
||||
attachmentObject.LocalId.ToString(),
|
||||
attachmentObject.FromItemID.ToString(),
|
||||
((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(),
|
||||
attachmentObject.RootPart.AttachedPos.ToString()
|
||||
}));
|
||||
attachmentObject.LocalId,
|
||||
attachmentObject.FromItemID,
|
||||
((AttachmentPoint)attachmentObject.AttachmentPoint),
|
||||
attachmentObject.RootPart.AttachedPos);
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ public override void SetShapeCollisionMargin(BulletShape shape, float margin)
|
|||
{
|
||||
BulletShapeUnman shapeu = shape as BulletShapeUnman;
|
||||
if (shapeu != null && shapeu.HasPhysicalShape)
|
||||
BSAPICPP.SetShapeCollisionMargin2(shapeu.ptr, margin);
|
||||
BSAPICPP.SetShapeCollisionMargin(shapeu.ptr, margin);
|
||||
}
|
||||
|
||||
public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale)
|
||||
|
@ -1420,7 +1420,7 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData)
|
|||
public static extern bool IsNativeShape2(IntPtr shape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetShapeCollisionMargin2(IntPtr shape, float margin);
|
||||
public static extern void SetShapeCollisionMargin(IntPtr shape, float margin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale);
|
||||
|
|
|
@ -1201,8 +1201,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
VehicleAddForce(appliedGravity);
|
||||
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}",
|
||||
Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity);
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
||||
Prim.LocalID, m_VehicleGravity,
|
||||
Prim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
|
|
@ -39,6 +39,20 @@ public static class BSParam
|
|||
{
|
||||
private static string LogHeader = "[BULLETSIM PARAMETERS]";
|
||||
|
||||
// Tuning notes:
|
||||
// From: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6575
|
||||
// Contact points can be added even if the distance is positive. The constraint solver can deal with
|
||||
// contacts with positive distances as well as negative (penetration). Contact points are discarded
|
||||
// if the distance exceeds a certain threshold.
|
||||
// Bullet has a contact processing threshold and a contact breaking threshold.
|
||||
// If the distance is larger than the contact breaking threshold, it will be removed after one frame.
|
||||
// If the distance is larger than the contact processing threshold, the constraint solver will ignore it.
|
||||
|
||||
// This is separate/independent from the collision margin. The collision margin increases the object a bit
|
||||
// to improve collision detection performance and accuracy.
|
||||
// ===================
|
||||
// From:
|
||||
|
||||
// Level of Detail values kept as float because that's what the Meshmerizer wants
|
||||
public static float MeshLOD { get; private set; }
|
||||
public static float MeshCircularLOD { get; private set; }
|
||||
|
@ -74,9 +88,11 @@ public static class BSParam
|
|||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||
|
||||
public static float TerrainImplementation { get; private set; }
|
||||
public static int TerrainMeshMagnification { get; private set; }
|
||||
public static float TerrainFriction { get; private set; }
|
||||
public static float TerrainHitFraction { get; private set; }
|
||||
public static float TerrainRestitution { get; private set; }
|
||||
public static float TerrainContactProcessingThreshold { get; private set; }
|
||||
public static float TerrainCollisionMargin { get; private set; }
|
||||
|
||||
public static float DefaultFriction { get; private set; }
|
||||
|
@ -446,6 +462,10 @@ public static class BSParam
|
|||
(float)BSTerrainPhys.TerrainImplementation.Mesh,
|
||||
(s) => { return TerrainImplementation; },
|
||||
(s,v) => { TerrainImplementation = v; } ),
|
||||
new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
|
||||
3,
|
||||
(s) => { return TerrainMeshMagnification; },
|
||||
(s,v) => { TerrainMeshMagnification = v; } ),
|
||||
new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" ,
|
||||
0.3f,
|
||||
(s) => { return TerrainFriction; },
|
||||
|
@ -458,6 +478,10 @@ public static class BSParam
|
|||
0f,
|
||||
(s) => { return TerrainRestitution; },
|
||||
(s,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
|
||||
new ParameterDefn<float>("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" ,
|
||||
0.0f,
|
||||
(s) => { return TerrainContactProcessingThreshold; },
|
||||
(s,v) => { TerrainContactProcessingThreshold = v; /* TODO: set on real terrain */ } ),
|
||||
new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" ,
|
||||
0.08f,
|
||||
(s) => { return TerrainCollisionMargin; },
|
||||
|
|
|
@ -947,9 +947,9 @@ public class BSPrim : BSPhysObject
|
|||
ZeroMotion(true);
|
||||
|
||||
// Set various physical properties so other object interact properly
|
||||
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
|
||||
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||
PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
|
||||
// Mass is zero which disables a bunch of physics stuff in Bullet
|
||||
UpdatePhysicalMassProperties(0f, false);
|
||||
|
|
|
@ -687,7 +687,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}",
|
||||
PhysicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}",
|
||||
LogHeader, prim.PhysObjectName, prim.RawPosition, PhysicsScene.Name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,6 +263,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
|
||||
if (MegaRegionParentPhysicsScene == null)
|
||||
{
|
||||
// This terrain is not part of the mega-region scheme. Create vanilla terrain.
|
||||
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
||||
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
||||
|
||||
|
|
|
@ -76,11 +76,26 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
m_sizeX = (int)(maxCoords.X - minCoords.X);
|
||||
m_sizeY = (int)(maxCoords.Y - minCoords.Y);
|
||||
|
||||
if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap,
|
||||
m_sizeX, m_sizeY,
|
||||
(float)m_sizeX, (float)m_sizeY,
|
||||
Vector3.Zero, 1.0f,
|
||||
out indicesCount, out indices, out verticesCount, out vertices))
|
||||
bool meshCreationSuccess = false;
|
||||
if (BSParam.TerrainMeshMagnification == 1)
|
||||
{
|
||||
// If a magnification of one, use the old routine that is tried and true.
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene,
|
||||
initialMap, m_sizeX, m_sizeY, // input size
|
||||
Vector3.Zero, // base for mesh
|
||||
out indicesCount, out indices, out verticesCount, out vertices);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Other magnifications use the newer routine
|
||||
meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(PhysicsScene,
|
||||
initialMap, m_sizeX, m_sizeY, // input size
|
||||
BSParam.TerrainMeshMagnification,
|
||||
physicsScene.TerrainManager.DefaultRegionSize,
|
||||
Vector3.Zero, // base for mesh
|
||||
out indicesCount, out indices, out verticesCount, out vertices);
|
||||
}
|
||||
if (!meshCreationSuccess)
|
||||
{
|
||||
// DISASTER!!
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID);
|
||||
|
@ -88,6 +103,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
// Something is very messed up and a crash is in our future.
|
||||
return;
|
||||
}
|
||||
|
||||
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
|
||||
ID, indicesCount, indices.Length, verticesCount, vertices.Length);
|
||||
|
||||
|
@ -112,11 +128,13 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
// Something is very messed up and a crash is in our future.
|
||||
return;
|
||||
}
|
||||
physicsScene.PE.SetShapeCollisionMargin(m_terrainShape, BSParam.TerrainCollisionMargin);
|
||||
|
||||
// Set current terrain attributes
|
||||
PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
|
||||
PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
|
||||
PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold);
|
||||
PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
// Static objects are not very massive.
|
||||
|
@ -184,9 +202,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
// Return 'true' if successfully created.
|
||||
public static bool ConvertHeightmapToMesh( BSScene physicsScene,
|
||||
float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap
|
||||
float extentX, float extentY, // zero based range for output vertices
|
||||
Vector3 extentBase, // base to be added to all vertices
|
||||
float magnification, // number of vertices to create between heightMap coords
|
||||
out int indicesCountO, out int[] indicesO,
|
||||
out int verticesCountO, out float[] verticesO)
|
||||
{
|
||||
|
@ -207,17 +223,15 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
// of the heightmap.
|
||||
try
|
||||
{
|
||||
// One vertice per heightmap value plus the vertices off the top and bottom edge.
|
||||
// One vertice per heightmap value plus the vertices off the side and bottom edge.
|
||||
int totalVertices = (sizeX + 1) * (sizeY + 1);
|
||||
vertices = new float[totalVertices * 3];
|
||||
int totalIndices = sizeX * sizeY * 6;
|
||||
indices = new int[totalIndices];
|
||||
|
||||
float magX = (float)sizeX / extentX;
|
||||
float magY = (float)sizeY / extentY;
|
||||
if (physicsScene != null)
|
||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
|
||||
BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
|
||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3}",
|
||||
BSScene.DetailLogZero, totalVertices, totalIndices, extentBase);
|
||||
float minHeight = float.MaxValue;
|
||||
// Note that sizeX+1 vertices are created since there is land between this and the next region.
|
||||
for (int yy = 0; yy <= sizeY; yy++)
|
||||
|
@ -230,8 +244,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
if (xx == sizeX) offset -= 1;
|
||||
float height = heightMap[offset];
|
||||
minHeight = Math.Min(minHeight, height);
|
||||
vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
|
||||
vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
|
||||
vertices[verticesCount + 0] = (float)xx + extentBase.X;
|
||||
vertices[verticesCount + 1] = (float)yy + extentBase.Y;
|
||||
vertices[verticesCount + 2] = height + extentBase.Z;
|
||||
verticesCount += 3;
|
||||
}
|
||||
|
@ -270,5 +284,158 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private class HeightMapGetter
|
||||
{
|
||||
private float[] m_heightMap;
|
||||
private int m_sizeX;
|
||||
private int m_sizeY;
|
||||
public HeightMapGetter(float[] pHeightMap, int pSizeX, int pSizeY)
|
||||
{
|
||||
m_heightMap = pHeightMap;
|
||||
m_sizeX = pSizeX;
|
||||
m_sizeY = pSizeY;
|
||||
}
|
||||
// The heightmap is extended as an infinite plane at the last height
|
||||
public float GetHeight(int xx, int yy)
|
||||
{
|
||||
int offset = 0;
|
||||
// Extend the height with the height from the last row or column
|
||||
if (yy >= m_sizeY)
|
||||
if (xx >= m_sizeX)
|
||||
offset = (m_sizeY - 1) * m_sizeX + (m_sizeX - 1);
|
||||
else
|
||||
offset = (m_sizeY - 1) * m_sizeX + xx;
|
||||
else
|
||||
if (xx >= m_sizeX)
|
||||
offset = yy * m_sizeX + (m_sizeX - 1);
|
||||
else
|
||||
offset = yy * m_sizeX + xx;
|
||||
|
||||
return m_heightMap[offset];
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
|
||||
// Version that handles magnification.
|
||||
// Return 'true' if successfully created.
|
||||
public static bool ConvertHeightmapToMesh2( BSScene physicsScene,
|
||||
float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap
|
||||
int magnification, // number of vertices per heighmap step
|
||||
Vector3 extent, // dimensions of the output mesh
|
||||
Vector3 extentBase, // base to be added to all vertices
|
||||
out int indicesCountO, out int[] indicesO,
|
||||
out int verticesCountO, out float[] verticesO)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
int indicesCount = 0;
|
||||
int verticesCount = 0;
|
||||
int[] indices = new int[0];
|
||||
float[] vertices = new float[0];
|
||||
|
||||
HeightMapGetter hmap = new HeightMapGetter(heightMap, sizeX, sizeY);
|
||||
|
||||
// The vertices dimension of the output mesh
|
||||
int meshX = sizeX * magnification;
|
||||
int meshY = sizeY * magnification;
|
||||
// The output size of one mesh step
|
||||
float meshXStep = extent.X / meshX;
|
||||
float meshYStep = extent.Y / meshY;
|
||||
|
||||
// Create an array of vertices that is meshX+1 by meshY+1 (note the loop
|
||||
// from zero to <= meshX). The triangle indices are then generated as two triangles
|
||||
// per heightmap point. There are meshX by meshY of these squares. The extra row and
|
||||
// column of vertices are used to complete the triangles of the last row and column
|
||||
// of the heightmap.
|
||||
try
|
||||
{
|
||||
// Vertices for the output heightmap plus one on the side and bottom to complete triangles
|
||||
int totalVertices = (meshX + 1) * (meshY + 1);
|
||||
vertices = new float[totalVertices * 3];
|
||||
int totalIndices = meshX * meshY * 6;
|
||||
indices = new int[totalIndices];
|
||||
|
||||
if (physicsScene != null)
|
||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,inSize={1},outSize={2},totVert={3},totInd={4},extentBase={5}",
|
||||
BSScene.DetailLogZero, new Vector2(sizeX, sizeY), new Vector2(meshX, meshY),
|
||||
totalVertices, totalIndices, extentBase);
|
||||
|
||||
float minHeight = float.MaxValue;
|
||||
// Note that sizeX+1 vertices are created since there is land between this and the next region.
|
||||
// Loop through the output vertices and compute the mediun height in between the input vertices
|
||||
for (int yy = 0; yy <= meshY; yy++)
|
||||
{
|
||||
for (int xx = 0; xx <= meshX; xx++) // Hint: the "<=" means we go around sizeX + 1 times
|
||||
{
|
||||
float offsetY = (float)yy * (float)sizeY / (float)meshY; // The Y that is closest to the mesh point
|
||||
int stepY = (int)offsetY;
|
||||
float fractionalY = offsetY - (float)stepY;
|
||||
float offsetX = (float)xx * (float)sizeX / (float)meshX; // The X that is closest to the mesh point
|
||||
int stepX = (int)offsetX;
|
||||
float fractionalX = offsetX - (float)stepX;
|
||||
|
||||
// physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,xx={1},yy={2},offX={3},stepX={4},fractX={5},offY={6},stepY={7},fractY={8}",
|
||||
// BSScene.DetailLogZero, xx, yy, offsetX, stepX, fractionalX, offsetY, stepY, fractionalY);
|
||||
|
||||
// get the four corners of the heightmap square the mesh point is in
|
||||
float heightUL = hmap.GetHeight(stepX , stepY );
|
||||
float heightUR = hmap.GetHeight(stepX + 1, stepY );
|
||||
float heightLL = hmap.GetHeight(stepX , stepY + 1);
|
||||
float heightLR = hmap.GetHeight(stepX + 1, stepY + 1);
|
||||
|
||||
// bilinear interplolation
|
||||
float height = heightUL * (1 - fractionalX) * (1 - fractionalY)
|
||||
+ heightUR * fractionalX * (1 - fractionalY)
|
||||
+ heightLL * (1 - fractionalX) * fractionalY
|
||||
+ heightLR * fractionalX * fractionalY;
|
||||
|
||||
// physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,heightUL={1},heightUR={2},heightLL={3},heightLR={4},heightMap={5}",
|
||||
// BSScene.DetailLogZero, heightUL, heightUR, heightLL, heightLR, height);
|
||||
|
||||
minHeight = Math.Min(minHeight, height);
|
||||
|
||||
vertices[verticesCount + 0] = (float)xx * meshXStep + extentBase.X;
|
||||
vertices[verticesCount + 1] = (float)yy * meshYStep + extentBase.Y;
|
||||
vertices[verticesCount + 2] = height + extentBase.Z;
|
||||
verticesCount += 3;
|
||||
}
|
||||
}
|
||||
// The number of vertices generated
|
||||
verticesCount /= 3;
|
||||
|
||||
// Loop through all the heightmap squares and create indices for the two triangles for that square
|
||||
for (int yy = 0; yy < meshY; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < meshX; xx++)
|
||||
{
|
||||
int offset = yy * (meshX + 1) + xx;
|
||||
// Each vertices is presumed to be the upper left corner of a box of two triangles
|
||||
indices[indicesCount + 0] = offset;
|
||||
indices[indicesCount + 1] = offset + 1;
|
||||
indices[indicesCount + 2] = offset + meshX + 1; // accounting for the extra column
|
||||
indices[indicesCount + 3] = offset + 1;
|
||||
indices[indicesCount + 4] = offset + meshX + 2;
|
||||
indices[indicesCount + 5] = offset + meshX + 1;
|
||||
indicesCount += 6;
|
||||
}
|
||||
}
|
||||
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (physicsScene != null)
|
||||
physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}",
|
||||
LogHeader, physicsScene.RegionName, extentBase, e);
|
||||
}
|
||||
|
||||
indicesCountO = indicesCount;
|
||||
indicesO = indices;
|
||||
verticesCountO = verticesCount;
|
||||
verticesO = vertices;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.CoreModules.Framework;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Tests.Common
|
||||
{
|
||||
public static class EntityTransferHelpers
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Set up correct handling of the InformClientOfNeighbour call from the source region that triggers the
|
||||
/// viewer to setup a connection with the destination region.
|
||||
/// </summary>
|
||||
/// <param name='tc'></param>
|
||||
/// <param name='neighbourTcs'>
|
||||
/// A list that will be populated with any TestClients set up in response to
|
||||
/// being informed about a destination region.
|
||||
/// </param>
|
||||
public static void SetUpInformClientOfNeighbour(TestClient tc, List<TestClient> neighbourTcs)
|
||||
{
|
||||
// XXX: Confusingly, this is also used for non-neighbour notification (as in teleports that do not use the
|
||||
// event queue).
|
||||
|
||||
tc.OnTestClientInformClientOfNeighbour += (neighbourHandle, neighbourExternalEndPoint) =>
|
||||
{
|
||||
uint x, y;
|
||||
Utils.LongToUInts(neighbourHandle, out x, out y);
|
||||
x /= Constants.RegionSize;
|
||||
y /= Constants.RegionSize;
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}",
|
||||
x, y, neighbourExternalEndPoint);
|
||||
|
||||
// In response to this message, we are going to make a teleport to the scene we've previous been told
|
||||
// about by test code (this needs to be improved).
|
||||
AgentCircuitData newAgent = tc.RequestClientInfo();
|
||||
|
||||
Scene neighbourScene;
|
||||
SceneManager.Instance.TryGetScene(x, y, out neighbourScene);
|
||||
|
||||
TestClient neighbourTc = new TestClient(newAgent, neighbourScene, SceneManager.Instance);
|
||||
neighbourTcs.Add(neighbourTc);
|
||||
neighbourScene.AddNewClient(neighbourTc, PresenceType.User);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -531,6 +531,31 @@ namespace OpenSim.Tests.Common
|
|||
/// <param name="sceneManager"></param>
|
||||
/// <returns></returns>
|
||||
public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData, SceneManager sceneManager)
|
||||
{
|
||||
return AddScenePresence(scene, new TestClient(agentData, scene, sceneManager), agentData, sceneManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a root agent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This function
|
||||
///
|
||||
/// 1) Tells the scene that an agent is coming. Normally, the login service (local if standalone, from the
|
||||
/// userserver if grid) would give initial login data back to the client and separately tell the scene that the
|
||||
/// agent was coming.
|
||||
///
|
||||
/// 2) Connects the agent with the scene
|
||||
///
|
||||
/// This function performs actions equivalent with notifying the scene that an agent is
|
||||
/// coming and then actually connecting the agent to the scene. The one step missed out is the very first
|
||||
/// </remarks>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="agentData"></param>
|
||||
/// <param name="sceneManager"></param>
|
||||
/// <returns></returns>
|
||||
public static ScenePresence AddScenePresence(
|
||||
Scene scene, IClientAPI client, AgentCircuitData agentData, SceneManager sceneManager)
|
||||
{
|
||||
// We emulate the proper login sequence here by doing things in four stages
|
||||
|
||||
|
@ -541,7 +566,7 @@ namespace OpenSim.Tests.Common
|
|||
lpsc.m_PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID);
|
||||
|
||||
// Stages 1 & 2
|
||||
ScenePresence sp = IntroduceClientToScene(scene, sceneManager, agentData, TeleportFlags.ViaLogin);
|
||||
ScenePresence sp = IntroduceClientToScene(scene, client, agentData, TeleportFlags.ViaLogin);
|
||||
|
||||
// Stage 3: Complete the entrance into the region. This converts the child agent into a root agent.
|
||||
sp.CompleteMovement(sp.ControllingClient, true);
|
||||
|
@ -558,11 +583,11 @@ namespace OpenSim.Tests.Common
|
|||
/// neighbours and where no teleporting takes place.
|
||||
/// </param>
|
||||
/// <param name='scene'></param>
|
||||
/// <param name='sceneManager></param>
|
||||
/// <param name='testClient'></param>
|
||||
/// <param name='agentData'></param>
|
||||
/// <param name='tf'></param>
|
||||
private static ScenePresence IntroduceClientToScene(
|
||||
Scene scene, SceneManager sceneManager, AgentCircuitData agentData, TeleportFlags tf)
|
||||
Scene scene, IClientAPI client, AgentCircuitData agentData, TeleportFlags tf)
|
||||
{
|
||||
string reason;
|
||||
|
||||
|
@ -571,10 +596,9 @@ namespace OpenSim.Tests.Common
|
|||
Console.WriteLine("NewUserConnection failed: " + reason);
|
||||
|
||||
// Stage 2: add the new client as a child agent to the scene
|
||||
TestClient client = new TestClient(agentData, scene, sceneManager);
|
||||
scene.AddNewClient(client, PresenceType.User);
|
||||
|
||||
return scene.GetScenePresence(agentData.AgentID);
|
||||
return scene.GetScenePresence(client.AgentId);
|
||||
}
|
||||
|
||||
public static ScenePresence AddChildScenePresence(Scene scene, UUID agentId)
|
||||
|
@ -583,7 +607,8 @@ namespace OpenSim.Tests.Common
|
|||
acd.child = true;
|
||||
|
||||
// XXX: ViaLogin may not be correct for child agents
|
||||
return IntroduceClientToScene(scene, null, acd, TeleportFlags.ViaLogin);
|
||||
TestClient client = new TestClient(acd, scene, null);
|
||||
return IntroduceClientToScene(scene, client, acd, TeleportFlags.ViaLogin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -46,8 +46,6 @@ namespace OpenSim.Tests.Common.Mock
|
|||
|
||||
EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing");
|
||||
|
||||
private TestClient TeleportSceneClient;
|
||||
|
||||
private Scene m_scene;
|
||||
private SceneManager m_sceneManager;
|
||||
|
||||
|
@ -60,7 +58,9 @@ namespace OpenSim.Tests.Common.Mock
|
|||
public List<ImagePacketPacket> SentImagePacketPackets { get; private set; }
|
||||
public List<ImageNotInDatabasePacket> SentImageNotInDatabasePackets { get; private set; }
|
||||
|
||||
// Test client specific events - for use by tests to implement some IClientAPI behaviour.
|
||||
public event Action<RegionInfo, Vector3, Vector3> OnReceivedMoveAgentIntoRegion;
|
||||
public event Action<ulong, IPEndPoint> OnTestClientInformClientOfNeighbour;
|
||||
|
||||
// disable warning: public events, part of the public API
|
||||
#pragma warning disable 67
|
||||
|
@ -604,23 +604,8 @@ namespace OpenSim.Tests.Common.Mock
|
|||
|
||||
public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint)
|
||||
{
|
||||
m_log.DebugFormat("[TEST CLIENT]: Processing inform client of neighbour");
|
||||
|
||||
// In response to this message, we are going to make a teleport to the scene we've previous been told
|
||||
// about by test code (this needs to be improved).
|
||||
AgentCircuitData newAgent = RequestClientInfo();
|
||||
|
||||
// Stage 2: add the new client as a child agent to the scene
|
||||
uint x, y;
|
||||
Utils.LongToUInts(neighbourHandle, out x, out y);
|
||||
x /= Constants.RegionSize;
|
||||
y /= Constants.RegionSize;
|
||||
|
||||
Scene neighbourScene;
|
||||
m_sceneManager.TryGetScene(x, y, out neighbourScene);
|
||||
|
||||
TeleportSceneClient = new TestClient(newAgent, neighbourScene, m_sceneManager);
|
||||
neighbourScene.AddNewClient(TeleportSceneClient, PresenceType.User);
|
||||
if (OnTestClientInformClientOfNeighbour != null)
|
||||
OnTestClientInformClientOfNeighbour(neighbourHandle, neighbourExternalEndPoint);
|
||||
}
|
||||
|
||||
public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
|
||||
|
@ -635,12 +620,6 @@ namespace OpenSim.Tests.Common.Mock
|
|||
// CompleteTeleportClientSide();
|
||||
}
|
||||
|
||||
public void CompleteTeleportClientSide()
|
||||
{
|
||||
TeleportSceneClient.CompleteMovement();
|
||||
//TeleportTargetScene.AgentCrossing(newAgent.AgentID, new Vector3(90, 90, 90), false);
|
||||
}
|
||||
|
||||
public virtual void SendTeleportFailed(string reason)
|
||||
{
|
||||
m_log.DebugFormat("[TEST CLIENT]: Teleport failed with reason {0}", reason);
|
||||
|
|
Loading…
Reference in New Issue