diff options
Diffstat (limited to 'OpenSim/Region')
30 files changed, 1023 insertions, 396 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index f6e501d..37285e3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -97,6 +97,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
97 | + " >= 1 - turns on outgoing event logging\n" | 97 | + " >= 1 - turns on outgoing event logging\n" |
98 | + " >= 2 - turns on poll notification", | 98 | + " >= 2 - turns on poll notification", |
99 | HandleDebugEq); | 99 | HandleDebugEq); |
100 | |||
101 | MainConsole.Instance.Commands.AddCommand( | ||
102 | "Debug", | ||
103 | false, | ||
104 | "show eq", | ||
105 | "show eq", | ||
106 | "Show contents of event queues for logged in avatars. Used for debugging.", | ||
107 | HandleShowEq); | ||
100 | } | 108 | } |
101 | 109 | ||
102 | public void RemoveRegion(Scene scene) | 110 | public void RemoveRegion(Scene scene) |
@@ -138,7 +146,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
138 | 146 | ||
139 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | 147 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) |
140 | { | 148 | { |
141 | MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]"); | 149 | MainConsole.Instance.OutputFormat("Usage: debug eq [0|1|2]"); |
142 | } | 150 | } |
143 | else | 151 | else |
144 | { | 152 | { |
@@ -148,6 +156,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
148 | } | 156 | } |
149 | } | 157 | } |
150 | 158 | ||
159 | protected void HandleShowEq(string module, string[] args) | ||
160 | { | ||
161 | MainConsole.Instance.OutputFormat("For scene {0}", m_scene.Name); | ||
162 | |||
163 | lock (queues) | ||
164 | { | ||
165 | foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues) | ||
166 | { | ||
167 | MainConsole.Instance.OutputFormat( | ||
168 | "For agent {0} there are {1} messages queued for send.", | ||
169 | kvp.Key, kvp.Value.Count); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
151 | /// <summary> | 174 | /// <summary> |
152 | /// Always returns a valid queue | 175 | /// Always returns a valid queue |
153 | /// </summary> | 176 | /// </summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 6ef8815..7d9f935 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | |||
@@ -70,6 +70,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
70 | 70 | ||
71 | private string m_MapImageServerURL = string.Empty; | 71 | private string m_MapImageServerURL = string.Empty; |
72 | private string m_SearchURL = string.Empty; | 72 | private string m_SearchURL = string.Empty; |
73 | private bool m_ExportSupported = false; | ||
73 | 74 | ||
74 | #region ISharedRegionModule Members | 75 | #region ISharedRegionModule Members |
75 | 76 | ||
@@ -87,6 +88,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
87 | } | 88 | } |
88 | 89 | ||
89 | m_SearchURL = config.GetString("SearchServerURI", string.Empty); | 90 | m_SearchURL = config.GetString("SearchServerURI", string.Empty); |
91 | |||
92 | m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); | ||
90 | } | 93 | } |
91 | 94 | ||
92 | AddDefaultFeatures(); | 95 | AddDefaultFeatures(); |
@@ -152,6 +155,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
152 | if (m_SearchURL != string.Empty) | 155 | if (m_SearchURL != string.Empty) |
153 | gridServicesMap["search"] = m_SearchURL; | 156 | gridServicesMap["search"] = m_SearchURL; |
154 | m_features["GridServices"] = gridServicesMap; | 157 | m_features["GridServices"] = gridServicesMap; |
158 | |||
159 | if (m_ExportSupported) | ||
160 | m_features["ExportSupported"] = true; | ||
155 | } | 161 | } |
156 | } | 162 | } |
157 | 163 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f62512e..cb724aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
49 | { | 49 | { |
50 | #region INonSharedRegionModule | 50 | #region INonSharedRegionModule |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | |||
53 | public int DebugLevel { get; set; } | ||
52 | 54 | ||
53 | private Scene m_scene; | 55 | private Scene m_scene; |
54 | private IInventoryAccessModule m_invAccessModule; | 56 | private IInventoryAccessModule m_invAccessModule; |
@@ -76,10 +78,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
76 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | 78 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); |
77 | 79 | ||
78 | if (Enabled) | 80 | if (Enabled) |
81 | { | ||
79 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 82 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
83 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | ||
84 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | ||
85 | |||
86 | MainConsole.Instance.Commands.AddCommand( | ||
87 | "Debug", | ||
88 | false, | ||
89 | "debug attachments", | ||
90 | "debug attachments [0|1]", | ||
91 | "Turn on attachments debugging\n" | ||
92 | + " <= 0 - turns off debugging\n" | ||
93 | + " >= 1 - turns on attachment message logging\n", | ||
94 | HandleDebugAttachments); | ||
95 | } | ||
80 | 96 | ||
81 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI | 97 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI |
82 | } | 98 | } |
99 | |||
100 | private void HandleDebugAttachments(string module, string[] args) | ||
101 | { | ||
102 | int debugLevel; | ||
103 | |||
104 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | ||
105 | { | ||
106 | MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | DebugLevel = debugLevel; | ||
111 | MainConsole.Instance.OutputFormat( | ||
112 | "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /// <summary> | ||
117 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. | ||
118 | /// </summary> | ||
119 | /// <param name='localID'></param> | ||
120 | /// <param name='itemID'></param> | ||
121 | private void HandleScriptStateChange(uint localID, bool started) | ||
122 | { | ||
123 | SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); | ||
124 | if (sog != null && sog.IsAttachment) | ||
125 | { | ||
126 | if (!started) | ||
127 | { | ||
128 | // FIXME: This is a convoluted way for working out whether the script state has changed to stop | ||
129 | // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below | ||
130 | // This needs to be handled in a less tangled way. | ||
131 | ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar); | ||
132 | if (sp.ControllingClient.IsActive) | ||
133 | sog.HasGroupChanged = true; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | sog.HasGroupChanged = true; | ||
138 | } | ||
139 | } | ||
140 | } | ||
83 | 141 | ||
84 | public void RemoveRegion(Scene scene) | 142 | public void RemoveRegion(Scene scene) |
85 | { | 143 | { |
@@ -153,10 +211,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
153 | } | 211 | } |
154 | } | 212 | } |
155 | 213 | ||
156 | /// <summary> | ||
157 | /// RezAttachments. This should only be called upon login on the first region. | ||
158 | /// Attachment rezzings on crossings and TPs are done in a different way. | ||
159 | /// </summary> | ||
160 | public void RezAttachments(IScenePresence sp) | 214 | public void RezAttachments(IScenePresence sp) |
161 | { | 215 | { |
162 | if (!Enabled) | 216 | if (!Enabled) |
@@ -165,10 +219,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
165 | if (null == sp.Appearance) | 219 | if (null == sp.Appearance) |
166 | { | 220 | { |
167 | m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); | 221 | m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); |
222 | |||
168 | return; | 223 | return; |
169 | } | 224 | } |
170 | 225 | ||
171 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); | 226 | if (sp.GetAttachments().Count > 0) |
227 | { | ||
228 | if (DebugLevel > 0) | ||
229 | m_log.DebugFormat( | ||
230 | "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", | ||
231 | m_scene.Name, sp.Name); | ||
232 | |||
233 | return; | ||
234 | } | ||
235 | |||
236 | if (DebugLevel > 0) | ||
237 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); | ||
172 | 238 | ||
173 | XmlDocument doc = new XmlDocument(); | 239 | XmlDocument doc = new XmlDocument(); |
174 | string stateData = String.Empty; | 240 | string stateData = String.Empty; |
@@ -235,10 +301,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
235 | 301 | ||
236 | // If we're an NPC then skip all the item checks and manipulations since we don't have an | 302 | // If we're an NPC then skip all the item checks and manipulations since we don't have an |
237 | // inventory right now. | 303 | // inventory right now. |
238 | if (sp.PresenceType == PresenceType.Npc) | 304 | RezSingleAttachmentFromInventoryInternal( |
239 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true); | 305 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null); |
240 | else | ||
241 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d); | ||
242 | } | 306 | } |
243 | catch (Exception e) | 307 | catch (Exception e) |
244 | { | 308 | { |
@@ -254,7 +318,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
254 | if (!Enabled) | 318 | if (!Enabled) |
255 | return; | 319 | return; |
256 | 320 | ||
257 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | 321 | if (DebugLevel > 0) |
322 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
258 | 323 | ||
259 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 324 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
260 | 325 | ||
@@ -287,9 +352,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
287 | if (!Enabled) | 352 | if (!Enabled) |
288 | return; | 353 | return; |
289 | 354 | ||
290 | // m_log.DebugFormat( | 355 | if (DebugLevel > 0) |
291 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | 356 | m_log.DebugFormat( |
292 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | 357 | "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", |
358 | m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
293 | 359 | ||
294 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 360 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
295 | { | 361 | { |
@@ -299,12 +365,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
299 | sp.ClearAttachments(); | 365 | sp.ClearAttachments(); |
300 | } | 366 | } |
301 | 367 | ||
302 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append) | 368 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append) |
303 | { | 369 | { |
304 | if (!Enabled) | 370 | if (!Enabled) |
305 | return false; | 371 | return false; |
306 | 372 | ||
307 | return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, false, append); | 373 | return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append); |
308 | } | 374 | } |
309 | 375 | ||
310 | /// <summary> | 376 | /// <summary> |
@@ -315,9 +381,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
315 | /// <param name='group'>The object to attach.</param> | 381 | /// <param name='group'>The object to attach.</param> |
316 | /// <param name='attachmentPt'></param> | 382 | /// <param name='attachmentPt'></param> |
317 | /// <param name='silent'></param> | 383 | /// <param name='silent'></param> |
318 | /// <param name='temp'></param> | 384 | /// <param name='addToInventory'>If true then add object to user inventory.</param> |
319 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> | 385 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> |
320 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool resumeScripts, bool append) | 386 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append) |
321 | { | 387 | { |
322 | // m_log.DebugFormat( | 388 | // m_log.DebugFormat( |
323 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | 389 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
@@ -334,9 +400,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
334 | 400 | ||
335 | if (group.GetSittingAvatarsCount() != 0) | 401 | if (group.GetSittingAvatarsCount() != 0) |
336 | { | 402 | { |
337 | // m_log.WarnFormat( | 403 | if (DebugLevel > 0) |
338 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | 404 | m_log.WarnFormat( |
339 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | 405 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", |
406 | group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | ||
340 | 407 | ||
341 | return false; | 408 | return false; |
342 | } | 409 | } |
@@ -372,6 +439,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
372 | 439 | ||
373 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 440 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); |
374 | 441 | ||
442 | if (attachments.Contains(group)) | ||
443 | { | ||
444 | if (DebugLevel > 0) | ||
445 | m_log.WarnFormat( | ||
446 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
447 | group.Name, group.LocalId, sp.Name, attachmentPt); | ||
448 | |||
449 | return false; | ||
450 | } | ||
451 | |||
375 | // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones | 452 | // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones |
376 | while (attachments.Count >= 5) | 453 | while (attachments.Count >= 5) |
377 | { | 454 | { |
@@ -395,8 +472,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
395 | group.AttachmentPoint = attachmentPt; | 472 | group.AttachmentPoint = attachmentPt; |
396 | group.AbsolutePosition = attachPos; | 473 | group.AbsolutePosition = attachPos; |
397 | 474 | ||
398 | if (sp.PresenceType != PresenceType.Npc) | 475 | if (addToInventory && sp.PresenceType != PresenceType.Npc) |
399 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); | 476 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); |
400 | 477 | ||
401 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | 478 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
402 | 479 | ||
@@ -415,17 +492,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
415 | return true; | 492 | return true; |
416 | } | 493 | } |
417 | 494 | ||
418 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) | 495 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool append) |
419 | { | 496 | { |
420 | // Add the new attachment to inventory if we don't already have it. | 497 | // Add the new attachment to inventory if we don't already have it. |
421 | if (!temp) | 498 | UUID newAttachmentItemID = group.FromItemID; |
422 | { | 499 | if (newAttachmentItemID == UUID.Zero) |
423 | UUID newAttachmentItemID = group.FromItemID; | 500 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; |
424 | if (newAttachmentItemID == UUID.Zero) | ||
425 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
426 | 501 | ||
427 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); | 502 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); |
428 | } | ||
429 | } | 503 | } |
430 | 504 | ||
431 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 505 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
@@ -438,40 +512,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
438 | if (!Enabled) | 512 | if (!Enabled) |
439 | return null; | 513 | return null; |
440 | 514 | ||
441 | // m_log.DebugFormat( | 515 | if (DebugLevel > 0) |
442 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", | 516 | m_log.DebugFormat( |
443 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); | 517 | "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", |
444 | 518 | (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); | |
445 | bool append = (AttachmentPt & 0x80) != 0; | ||
446 | AttachmentPt &= 0x7f; | ||
447 | 519 | ||
448 | // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). | 520 | // We check the attachments in the avatar appearance here rather than the objects attached to the |
449 | // This often happens during login - not sure the exact reason. | 521 | // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are |
450 | // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the | 522 | // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done |
451 | // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login | 523 | // because pre-outfit folder viewers (most version 1 viewers) require it. |
452 | // before anything has actually been attached. | ||
453 | bool alreadyOn = false; | 524 | bool alreadyOn = false; |
454 | List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); | 525 | List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments(); |
455 | foreach (SceneObjectGroup so in existingAttachments) | 526 | foreach (AvatarAttachment existingAttachment in existingAttachments) |
456 | { | 527 | { |
457 | if (so.FromItemID == itemID) | 528 | if (existingAttachment.ItemID == itemID) |
458 | { | 529 | { |
459 | alreadyOn = true; | 530 | alreadyOn = true; |
460 | break; | 531 | break; |
461 | } | 532 | } |
462 | } | 533 | } |
463 | 534 | ||
464 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) | ||
465 | if (alreadyOn) | 535 | if (alreadyOn) |
466 | { | 536 | { |
467 | // m_log.WarnFormat( | 537 | if (DebugLevel > 0) |
468 | // "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", | 538 | m_log.DebugFormat( |
469 | // sp.Name, itemID, AttachmentPt); | 539 | "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", |
540 | sp.Name, itemID, AttachmentPt); | ||
470 | 541 | ||
471 | return null; | 542 | return null; |
472 | } | 543 | } |
473 | 544 | ||
474 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append); | 545 | bool append = (AttachmentPt & 0x80) != 0; |
546 | AttachmentPt &= 0x7f; | ||
547 | |||
548 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc); | ||
475 | } | 549 | } |
476 | 550 | ||
477 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 551 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -479,7 +553,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
479 | if (!Enabled) | 553 | if (!Enabled) |
480 | return; | 554 | return; |
481 | 555 | ||
482 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | 556 | if (DebugLevel > 0) |
557 | m_log.DebugFormat( | ||
558 | "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}", | ||
559 | rezlist.Count, sp.Name, m_scene.Name); | ||
483 | 560 | ||
484 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | 561 | foreach (KeyValuePair<UUID, uint> rez in rezlist) |
485 | { | 562 | { |
@@ -497,9 +574,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
497 | if (!Enabled) | 574 | if (!Enabled) |
498 | return; | 575 | return; |
499 | 576 | ||
500 | // m_log.DebugFormat( | 577 | if (DebugLevel > 0) |
501 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 578 | m_log.DebugFormat( |
502 | // sp.UUID, soLocalId); | 579 | "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
580 | sp.UUID, soLocalId); | ||
503 | 581 | ||
504 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 582 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
505 | 583 | ||
@@ -515,9 +593,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
515 | if (inventoryID == UUID.Zero) | 593 | if (inventoryID == UUID.Zero) |
516 | return; | 594 | return; |
517 | 595 | ||
518 | // m_log.DebugFormat( | 596 | if (DebugLevel > 0) |
519 | // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", | 597 | m_log.DebugFormat( |
520 | // so.Name, so.LocalId, inventoryID); | 598 | "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", |
599 | so.Name, so.LocalId, inventoryID); | ||
521 | 600 | ||
522 | lock (sp.AttachmentsSyncLock) | 601 | lock (sp.AttachmentsSyncLock) |
523 | { | 602 | { |
@@ -572,9 +651,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
572 | return; | 651 | return; |
573 | } | 652 | } |
574 | 653 | ||
575 | // m_log.DebugFormat( | 654 | if (DebugLevel > 0) |
576 | // "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", | 655 | m_log.DebugFormat( |
577 | // so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); | 656 | "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", |
657 | so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); | ||
578 | 658 | ||
579 | // Scripts MUST be snapshotted before the object is | 659 | // Scripts MUST be snapshotted before the object is |
580 | // removed from the scene because doing otherwise will | 660 | // removed from the scene because doing otherwise will |
@@ -700,12 +780,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
700 | 780 | ||
701 | grp.HasGroupChanged = false; // Prevent it being saved over and over | 781 | grp.HasGroupChanged = false; // Prevent it being saved over and over |
702 | } | 782 | } |
703 | // else | 783 | else if (DebugLevel > 0) |
704 | // { | 784 | { |
705 | // m_log.DebugFormat( | 785 | m_log.DebugFormat( |
706 | // "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | 786 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", |
707 | // grp.UUID, grp.AttachmentPoint); | 787 | grp.UUID, grp.AttachmentPoint); |
708 | // } | 788 | } |
709 | } | 789 | } |
710 | 790 | ||
711 | /// <summary> | 791 | /// <summary> |
@@ -723,9 +803,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
723 | private void AttachToAgent( | 803 | private void AttachToAgent( |
724 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 804 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
725 | { | 805 | { |
726 | // m_log.DebugFormat( | 806 | if (DebugLevel > 0) |
727 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 807 | m_log.DebugFormat( |
728 | // so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 808 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", |
809 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | ||
729 | 810 | ||
730 | so.DetachFromBackup(); | 811 | so.DetachFromBackup(); |
731 | 812 | ||
@@ -750,9 +831,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
750 | { | 831 | { |
751 | if (so.HasPrivateAttachmentPoint) | 832 | if (so.HasPrivateAttachmentPoint) |
752 | { | 833 | { |
753 | // m_log.DebugFormat( | 834 | if (DebugLevel > 0) |
754 | // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", | 835 | m_log.DebugFormat( |
755 | // so.Name, sp.Name, so.AttachmentPoint); | 836 | "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", |
837 | so.Name, sp.Name, so.AttachmentPoint); | ||
756 | 838 | ||
757 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the | 839 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the |
758 | // scene that it's no longer in their awareness. | 840 | // scene that it's no longer in their awareness. |
@@ -786,9 +868,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
786 | if (m_invAccessModule == null) | 868 | if (m_invAccessModule == null) |
787 | return null; | 869 | return null; |
788 | 870 | ||
789 | // m_log.DebugFormat( | 871 | if (DebugLevel > 0) |
790 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | 872 | m_log.DebugFormat( |
791 | // grp.Name, grp.LocalId, remoteClient.Name); | 873 | "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", |
874 | grp.Name, grp.LocalId, sp.Name); | ||
792 | 875 | ||
793 | InventoryItemBase newItem | 876 | InventoryItemBase newItem |
794 | = m_invAccessModule.CopyToInventory( | 877 | = m_invAccessModule.CopyToInventory( |
@@ -872,7 +955,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
872 | } | 955 | } |
873 | 956 | ||
874 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 957 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
875 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append) | 958 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc) |
876 | { | 959 | { |
877 | if (m_invAccessModule == null) | 960 | if (m_invAccessModule == null) |
878 | return null; | 961 | return null; |
@@ -897,6 +980,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
897 | return null; | 980 | return null; |
898 | } | 981 | } |
899 | 982 | ||
983 | if (DebugLevel > 0) | ||
984 | m_log.DebugFormat( | ||
985 | "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | ||
986 | objatt.Name, sp.Name, attachmentPt, m_scene.Name); | ||
987 | |||
900 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 988 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
901 | objatt.HasGroupChanged = false; | 989 | objatt.HasGroupChanged = false; |
902 | bool tainted = false; | 990 | bool tainted = false; |
@@ -917,7 +1005,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
917 | objatt.ResetOwnerChangeFlag(); | 1005 | objatt.ResetOwnerChangeFlag(); |
918 | } | 1006 | } |
919 | 1007 | ||
920 | AttachObjectInternal(sp, objatt, attachmentPt, false, true, false, true, append); | 1008 | AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append); |
921 | } | 1009 | } |
922 | catch (Exception e) | 1010 | catch (Exception e) |
923 | { | 1011 | { |
@@ -971,9 +1059,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
971 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); | 1059 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); |
972 | if (changed && m_scene.AvatarFactory != null) | 1060 | if (changed && m_scene.AvatarFactory != null) |
973 | { | 1061 | { |
974 | // m_log.DebugFormat( | 1062 | if (DebugLevel > 0) |
975 | // "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", | 1063 | m_log.DebugFormat( |
976 | // sp.Name, att.Name, AttachmentPt); | 1064 | "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", |
1065 | sp.Name, att.Name, AttachmentPt); | ||
977 | 1066 | ||
978 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 1067 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
979 | } | 1068 | } |
@@ -988,9 +1077,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
988 | if (!Enabled) | 1077 | if (!Enabled) |
989 | return null; | 1078 | return null; |
990 | 1079 | ||
991 | // m_log.DebugFormat( | 1080 | if (DebugLevel > 0) |
992 | // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", | 1081 | m_log.DebugFormat( |
993 | // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | 1082 | "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", |
1083 | (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | ||
994 | 1084 | ||
995 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1085 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
996 | 1086 | ||
@@ -1021,9 +1111,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1021 | 1111 | ||
1022 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 1112 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
1023 | { | 1113 | { |
1024 | // m_log.DebugFormat( | 1114 | if (DebugLevel > 0) |
1025 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 1115 | m_log.DebugFormat( |
1026 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); | 1116 | "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", |
1117 | objectLocalID, remoteClient.Name, AttachmentPt, silent); | ||
1027 | 1118 | ||
1028 | if (!Enabled) | 1119 | if (!Enabled) |
1029 | return; | 1120 | return; |
@@ -1056,11 +1147,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1056 | AttachmentPt &= 0x7f; | 1147 | AttachmentPt &= 0x7f; |
1057 | 1148 | ||
1058 | // Calls attach with a Zero position | 1149 | // Calls attach with a Zero position |
1059 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false, append)) | 1150 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, false, append)) |
1060 | { | 1151 | { |
1061 | // m_log.Debug( | 1152 | if (DebugLevel > 0) |
1062 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | 1153 | m_log.Debug( |
1063 | // + ", AttachmentPoint: " + AttachmentPt); | 1154 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
1155 | + ", AttachmentPoint: " + AttachmentPt); | ||
1064 | 1156 | ||
1065 | // Save avatar attachment information | 1157 | // Save avatar attachment information |
1066 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | 1158 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index a8fe045..1a38619 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
130 | config.AddConfig("Modules"); | 130 | config.AddConfig("Modules"); |
131 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 131 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
132 | 132 | ||
133 | modules.Add(new AttachmentsModule()); | 133 | AttachmentsModule attMod = new AttachmentsModule(); |
134 | attMod.DebugLevel = 1; | ||
135 | modules.Add(attMod); | ||
134 | modules.Add(new BasicInventoryAccessModule()); | 136 | modules.Add(new BasicInventoryAccessModule()); |
135 | } | 137 | } |
136 | 138 | ||
@@ -197,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
197 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); | 199 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
198 | 200 | ||
199 | m_numberOfAttachEventsFired = 0; | 201 | m_numberOfAttachEventsFired = 0; |
200 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false); | 202 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false); |
201 | 203 | ||
202 | // Check status on scene presence | 204 | // Check status on scene presence |
203 | Assert.That(sp.HasAttachments(), Is.True); | 205 | Assert.That(sp.HasAttachments(), Is.True); |
@@ -244,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
244 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); | 246 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); |
245 | 247 | ||
246 | m_numberOfAttachEventsFired = 0; | 248 | m_numberOfAttachEventsFired = 0; |
247 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false, false); | 249 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false, false); |
248 | 250 | ||
249 | // Check status on scene presence | 251 | // Check status on scene presence |
250 | Assert.That(sp.HasAttachments(), Is.True); | 252 | Assert.That(sp.HasAttachments(), Is.True); |
@@ -277,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
277 | 279 | ||
278 | // Test wearing a different attachment from the ground. | 280 | // Test wearing a different attachment from the ground. |
279 | { | 281 | { |
280 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false); | 282 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false); |
281 | 283 | ||
282 | // Check status on scene presence | 284 | // Check status on scene presence |
283 | Assert.That(sp.HasAttachments(), Is.True); | 285 | Assert.That(sp.HasAttachments(), Is.True); |
@@ -310,7 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
310 | 312 | ||
311 | // Test rewearing an already worn attachment from ground. Nothing should happen. | 313 | // Test rewearing an already worn attachment from ground. Nothing should happen. |
312 | { | 314 | { |
313 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false); | 315 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false); |
314 | 316 | ||
315 | // Check status on scene presence | 317 | // Check status on scene presence |
316 | Assert.That(sp.HasAttachments(), Is.True); | 318 | Assert.That(sp.HasAttachments(), Is.True); |
@@ -368,7 +370,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
368 | sp2.AbsolutePosition = new Vector3(0, 0, 0); | 370 | sp2.AbsolutePosition = new Vector3(0, 0, 0); |
369 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); | 371 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); |
370 | 372 | ||
371 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false); | 373 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false); |
372 | 374 | ||
373 | Assert.That(sp.HasAttachments(), Is.False); | 375 | Assert.That(sp.HasAttachments(), Is.False); |
374 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 376 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); |
@@ -728,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
728 | public void TestRezAttachmentsOnAvatarEntrance() | 730 | public void TestRezAttachmentsOnAvatarEntrance() |
729 | { | 731 | { |
730 | TestHelpers.InMethod(); | 732 | TestHelpers.InMethod(); |
731 | // log4net.Config.XmlConfigurator.Configure(); | 733 | // TestHelpers.EnableLogging(); |
732 | 734 | ||
733 | Scene scene = CreateTestScene(); | 735 | Scene scene = CreateTestScene(); |
734 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | 736 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 6c9fd86..a34f2d2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -154,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
154 | 154 | ||
155 | void OnIncomingInstantMessage(GridInstantMessage im) | 155 | void OnIncomingInstantMessage(GridInstantMessage im) |
156 | { | 156 | { |
157 | if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) | 157 | if (im.dialog == (byte)InstantMessageDialog.RequestTeleport |
158 | || im.dialog == (byte)InstantMessageDialog.GodLikeRequestTeleport) | ||
158 | { | 159 | { |
159 | UUID sessionID = new UUID(im.imSessionID); | 160 | UUID sessionID = new UUID(im.imSessionID); |
160 | 161 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index f3adb95..0c64f19 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
165 | (uint)presence.AbsolutePosition.Y, | 165 | (uint)presence.AbsolutePosition.Y, |
166 | (uint)presence.AbsolutePosition.Z + 2); | 166 | (uint)presence.AbsolutePosition.Z + 2); |
167 | 167 | ||
168 | m_log.DebugFormat("[LURE]: TP invite with message {0}", message); | 168 | m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); |
169 | 169 | ||
170 | GridInstantMessage m; | 170 | GridInstantMessage m; |
171 | 171 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 25334b9..8082c1b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -33,6 +33,7 @@ using System.Threading; | |||
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Capabilities; | 34 | using OpenSim.Framework.Capabilities; |
35 | using OpenSim.Framework.Client; | 35 | using OpenSim.Framework.Client; |
36 | using OpenSim.Framework.Monitoring; | ||
36 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Region.Physics.Manager; | 39 | using OpenSim.Region.Physics.Manager; |
@@ -77,6 +78,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
77 | /// </remarks> | 78 | /// </remarks> |
78 | public bool DisableInterRegionTeleportCancellation { get; set; } | 79 | public bool DisableInterRegionTeleportCancellation { get; set; } |
79 | 80 | ||
81 | /// <summary> | ||
82 | /// Number of times inter-region teleport was attempted. | ||
83 | /// </summary> | ||
84 | private Stat m_interRegionTeleportAttempts; | ||
85 | |||
86 | /// <summary> | ||
87 | /// Number of times inter-region teleport was aborted (due to simultaneous client logout). | ||
88 | /// </summary> | ||
89 | private Stat m_interRegionTeleportAborts; | ||
90 | |||
91 | /// <summary> | ||
92 | /// Number of times inter-region teleport was successfully cancelled by the client. | ||
93 | /// </summary> | ||
94 | private Stat m_interRegionTeleportCancels; | ||
95 | |||
96 | /// <summary> | ||
97 | /// Number of times inter-region teleport failed due to server/client/network problems (e.g. viewer failed to | ||
98 | /// connect with destination region). | ||
99 | /// </summary> | ||
100 | /// <remarks> | ||
101 | /// This is not necessarily a problem for this simulator - in open-grid/hg conditions, viewer connectivity to | ||
102 | /// destination simulator is unknown. | ||
103 | /// </remarks> | ||
104 | private Stat m_interRegionTeleportFailures; | ||
105 | |||
80 | protected bool m_Enabled = false; | 106 | protected bool m_Enabled = false; |
81 | 107 | ||
82 | public Scene Scene { get; private set; } | 108 | public Scene Scene { get; private set; } |
@@ -91,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
91 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 117 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); |
92 | 118 | ||
93 | private IEventQueue m_eqModule; | 119 | private IEventQueue m_eqModule; |
120 | private IRegionCombinerModule m_regionCombinerModule; | ||
94 | 121 | ||
95 | #region ISharedRegionModule | 122 | #region ISharedRegionModule |
96 | 123 | ||
@@ -156,6 +183,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
156 | 183 | ||
157 | Scene = scene; | 184 | Scene = scene; |
158 | 185 | ||
186 | m_interRegionTeleportAttempts = | ||
187 | new Stat( | ||
188 | "InterRegionTeleportAttempts", | ||
189 | "Number of inter-region teleports attempted.", | ||
190 | "This does not count attempts which failed due to pre-conditions (e.g. target simulator refused access).\n" | ||
191 | + "You can get successfully teleports by subtracting aborts, cancels and teleport failures from this figure.", | ||
192 | "", | ||
193 | "entitytransfer", | ||
194 | Scene.Name, | ||
195 | StatType.Push, | ||
196 | null, | ||
197 | StatVerbosity.Debug); | ||
198 | |||
199 | m_interRegionTeleportAborts = | ||
200 | new Stat( | ||
201 | "InterRegionTeleportAborts", | ||
202 | "Number of inter-region teleports aborted due to client actions.", | ||
203 | "The chief action is simultaneous logout whilst teleporting.", | ||
204 | "", | ||
205 | "entitytransfer", | ||
206 | Scene.Name, | ||
207 | StatType.Push, | ||
208 | null, | ||
209 | StatVerbosity.Debug); | ||
210 | |||
211 | m_interRegionTeleportCancels = | ||
212 | new Stat( | ||
213 | "InterRegionTeleportCancels", | ||
214 | "Number of inter-region teleports cancelled by the client.", | ||
215 | null, | ||
216 | "", | ||
217 | "entitytransfer", | ||
218 | Scene.Name, | ||
219 | StatType.Push, | ||
220 | null, | ||
221 | StatVerbosity.Debug); | ||
222 | |||
223 | m_interRegionTeleportFailures = | ||
224 | new Stat( | ||
225 | "InterRegionTeleportFailures", | ||
226 | "Number of inter-region teleports that failed due to server/client/network issues.", | ||
227 | "This number may not be very helpful in open-grid/hg situations as the network connectivity/quality of destinations is uncontrollable.", | ||
228 | "", | ||
229 | "entitytransfer", | ||
230 | Scene.Name, | ||
231 | StatType.Push, | ||
232 | null, | ||
233 | StatVerbosity.Debug); | ||
234 | |||
235 | StatsManager.RegisterStat(m_interRegionTeleportAttempts); | ||
236 | StatsManager.RegisterStat(m_interRegionTeleportAborts); | ||
237 | StatsManager.RegisterStat(m_interRegionTeleportCancels); | ||
238 | StatsManager.RegisterStat(m_interRegionTeleportFailures); | ||
239 | |||
159 | scene.RegisterModuleInterface<IEntityTransferModule>(this); | 240 | scene.RegisterModuleInterface<IEntityTransferModule>(this); |
160 | scene.EventManager.OnNewClient += OnNewClient; | 241 | scene.EventManager.OnNewClient += OnNewClient; |
161 | } | 242 | } |
@@ -173,7 +254,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
173 | 254 | ||
174 | public virtual void Close() {} | 255 | public virtual void Close() {} |
175 | 256 | ||
176 | public virtual void RemoveRegion(Scene scene) {} | 257 | public virtual void RemoveRegion(Scene scene) |
258 | { | ||
259 | if (m_Enabled) | ||
260 | { | ||
261 | StatsManager.DeregisterStat(m_interRegionTeleportAttempts); | ||
262 | StatsManager.DeregisterStat(m_interRegionTeleportAborts); | ||
263 | StatsManager.DeregisterStat(m_interRegionTeleportCancels); | ||
264 | StatsManager.DeregisterStat(m_interRegionTeleportFailures); | ||
265 | } | ||
266 | } | ||
177 | 267 | ||
178 | public virtual void RegionLoaded(Scene scene) | 268 | public virtual void RegionLoaded(Scene scene) |
179 | { | 269 | { |
@@ -181,6 +271,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
181 | return; | 271 | return; |
182 | 272 | ||
183 | m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); | 273 | m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); |
274 | m_regionCombinerModule = Scene.RequestModuleInterface<IRegionCombinerModule>(); | ||
184 | } | 275 | } |
185 | 276 | ||
186 | #endregion | 277 | #endregion |
@@ -291,8 +382,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
291 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 382 | Vector3 emergencyPos = new Vector3(128, 128, 128); |
292 | 383 | ||
293 | m_log.WarnFormat( | 384 | m_log.WarnFormat( |
294 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | 385 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2} in {3}. Substituting {4}", |
295 | position, sp.Name, sp.UUID, emergencyPos); | 386 | position, sp.Name, sp.UUID, Scene.Name, emergencyPos); |
296 | 387 | ||
297 | position = emergencyPos; | 388 | position = emergencyPos; |
298 | } | 389 | } |
@@ -548,6 +639,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
548 | return; | 639 | return; |
549 | } | 640 | } |
550 | 641 | ||
642 | // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target | ||
643 | // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these | ||
644 | // as server attempts. | ||
645 | m_interRegionTeleportAttempts.Value++; | ||
646 | |||
551 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); | 647 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); |
552 | 648 | ||
553 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 649 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
@@ -600,6 +696,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
600 | bool logout = false; | 696 | bool logout = false; |
601 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 697 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) |
602 | { | 698 | { |
699 | m_interRegionTeleportFailures.Value++; | ||
700 | |||
603 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | 701 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); |
604 | 702 | ||
605 | m_log.DebugFormat( | 703 | m_log.DebugFormat( |
@@ -611,6 +709,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
611 | 709 | ||
612 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) | 710 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) |
613 | { | 711 | { |
712 | m_interRegionTeleportCancels.Value++; | ||
713 | |||
614 | m_log.DebugFormat( | 714 | m_log.DebugFormat( |
615 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", | 715 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", |
616 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 716 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -619,6 +719,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
619 | } | 719 | } |
620 | else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 720 | else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
621 | { | 721 | { |
722 | m_interRegionTeleportAborts.Value++; | ||
723 | |||
622 | m_log.DebugFormat( | 724 | m_log.DebugFormat( |
623 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", | 725 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", |
624 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 726 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -635,6 +737,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
635 | IClientIPEndpoint ipepClient; | 737 | IClientIPEndpoint ipepClient; |
636 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 738 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
637 | { | 739 | { |
740 | m_log.DebugFormat( | ||
741 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", | ||
742 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
743 | |||
638 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | 744 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); |
639 | #region IP Translation for NAT | 745 | #region IP Translation for NAT |
640 | // Uses ipepClient above | 746 | // Uses ipepClient above |
@@ -688,6 +794,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
688 | // establish th econnection to the destination which makes it return true. | 794 | // establish th econnection to the destination which makes it return true. |
689 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 795 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
690 | { | 796 | { |
797 | m_interRegionTeleportAborts.Value++; | ||
798 | |||
691 | m_log.DebugFormat( | 799 | m_log.DebugFormat( |
692 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", | 800 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", |
693 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 801 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -703,6 +811,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
703 | { | 811 | { |
704 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 812 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
705 | { | 813 | { |
814 | m_interRegionTeleportAborts.Value++; | ||
815 | |||
706 | m_log.DebugFormat( | 816 | m_log.DebugFormat( |
707 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", | 817 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", |
708 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 818 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -720,6 +830,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
720 | 830 | ||
721 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) | 831 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) |
722 | { | 832 | { |
833 | m_interRegionTeleportCancels.Value++; | ||
834 | |||
723 | m_log.DebugFormat( | 835 | m_log.DebugFormat( |
724 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", | 836 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", |
725 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 837 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -755,6 +867,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
755 | { | 867 | { |
756 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 868 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
757 | { | 869 | { |
870 | m_interRegionTeleportAborts.Value++; | ||
871 | |||
758 | m_log.DebugFormat( | 872 | m_log.DebugFormat( |
759 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", | 873 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", |
760 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 874 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
@@ -767,6 +881,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
767 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 881 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
768 | 882 | ||
769 | Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); | 883 | Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); |
884 | |||
770 | return; | 885 | return; |
771 | } | 886 | } |
772 | 887 | ||
@@ -808,15 +923,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
808 | // now we have a child agent in this region. | 923 | // now we have a child agent in this region. |
809 | sp.Reset(); | 924 | sp.Reset(); |
810 | } | 925 | } |
811 | |||
812 | // Commented pending deletion since this method no longer appears to do anything at all | ||
813 | // // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
814 | // if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | ||
815 | // { | ||
816 | // m_log.DebugFormat( | ||
817 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | ||
818 | // sp.UUID); | ||
819 | // } | ||
820 | } | 926 | } |
821 | 927 | ||
822 | /// <summary> | 928 | /// <summary> |
@@ -852,6 +958,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
852 | { | 958 | { |
853 | CleanupFailedInterRegionTeleport(sp, finalDestination); | 959 | CleanupFailedInterRegionTeleport(sp, finalDestination); |
854 | 960 | ||
961 | m_interRegionTeleportFailures.Value++; | ||
962 | |||
855 | sp.ControllingClient.SendTeleportFailed( | 963 | sp.ControllingClient.SendTeleportFailed( |
856 | string.Format( | 964 | string.Format( |
857 | "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason)); | 965 | "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason)); |
@@ -907,7 +1015,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
907 | 1015 | ||
908 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) | 1016 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) |
909 | { | 1017 | { |
910 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); | 1018 | if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
1019 | { | ||
1020 | Vector2 swCorner, neCorner; | ||
1021 | GetMegaregionViewRange(out swCorner, out neCorner); | ||
1022 | |||
1023 | m_log.DebugFormat( | ||
1024 | "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}", | ||
1025 | Scene.Name, swCorner, neCorner, newRegionX, newRegionY); | ||
1026 | |||
1027 | return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y); | ||
1028 | } | ||
1029 | else | ||
1030 | { | ||
1031 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); | ||
1032 | } | ||
911 | } | 1033 | } |
912 | 1034 | ||
913 | protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) | 1035 | protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) |
@@ -1011,6 +1133,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1011 | { | 1133 | { |
1012 | version = String.Empty; | 1134 | version = String.Empty; |
1013 | newpos = new Vector3(pos.X, pos.Y, pos.Z); | 1135 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
1136 | |||
1137 | // m_log.DebugFormat( | ||
1138 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); | ||
1139 | |||
1014 | uint neighbourx = scene.RegionInfo.RegionLocX; | 1140 | uint neighbourx = scene.RegionInfo.RegionLocX; |
1015 | uint neighboury = scene.RegionInfo.RegionLocY; | 1141 | uint neighboury = scene.RegionInfo.RegionLocY; |
1016 | const float boundaryDistance = 1.7f; | 1142 | const float boundaryDistance = 1.7f; |
@@ -1182,7 +1308,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1182 | Scene initiatingScene) | 1308 | Scene initiatingScene) |
1183 | { | 1309 | { |
1184 | Thread.Sleep(10000); | 1310 | Thread.Sleep(10000); |
1185 | 1311 | ||
1312 | m_log.DebugFormat( | ||
1313 | "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}", | ||
1314 | agent.Name, regionX, regionY, position, initiatingScene.Name); | ||
1315 | |||
1316 | agent.Scene.RequestTeleportLocation( | ||
1317 | agent.ControllingClient, | ||
1318 | Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize), | ||
1319 | position, | ||
1320 | agent.Lookat, | ||
1321 | (uint)Constants.TeleportFlags.ViaLocation); | ||
1322 | |||
1323 | /* | ||
1186 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); | 1324 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); |
1187 | if (im != null) | 1325 | if (im != null) |
1188 | { | 1326 | { |
@@ -1217,6 +1355,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1217 | }); | 1355 | }); |
1218 | 1356 | ||
1219 | } | 1357 | } |
1358 | */ | ||
1220 | } | 1359 | } |
1221 | 1360 | ||
1222 | private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) | 1361 | private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) |
@@ -1725,6 +1864,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1725 | } | 1864 | } |
1726 | 1865 | ||
1727 | /// <summary> | 1866 | /// <summary> |
1867 | /// Gets the range considered in view of this megaregion (assuming this is a megaregion). | ||
1868 | /// </summary> | ||
1869 | /// <remarks>Expressed in 256m units</remarks> | ||
1870 | /// <param name='swCorner'></param> | ||
1871 | /// <param name='neCorner'></param> | ||
1872 | private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) | ||
1873 | { | ||
1874 | Border[] northBorders = Scene.NorthBorders.ToArray(); | ||
1875 | Border[] eastBorders = Scene.EastBorders.ToArray(); | ||
1876 | |||
1877 | Vector2 extent = Vector2.Zero; | ||
1878 | for (int i = 0; i < eastBorders.Length; i++) | ||
1879 | { | ||
1880 | extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; | ||
1881 | } | ||
1882 | for (int i = 0; i < northBorders.Length; i++) | ||
1883 | { | ||
1884 | extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; | ||
1885 | } | ||
1886 | |||
1887 | // Loss of fraction on purpose | ||
1888 | extent.X = ((int)extent.X / (int)Constants.RegionSize); | ||
1889 | extent.Y = ((int)extent.Y / (int)Constants.RegionSize); | ||
1890 | |||
1891 | swCorner.X = Scene.RegionInfo.RegionLocX - 1; | ||
1892 | swCorner.Y = Scene.RegionInfo.RegionLocY - 1; | ||
1893 | neCorner.X = Scene.RegionInfo.RegionLocX + extent.X; | ||
1894 | neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y; | ||
1895 | } | ||
1896 | |||
1897 | /// <summary> | ||
1728 | /// Return the list of regions that are considered to be neighbours to the given scene. | 1898 | /// Return the list of regions that are considered to be neighbours to the given scene. |
1729 | /// </summary> | 1899 | /// </summary> |
1730 | /// <param name="pScene"></param> | 1900 | /// <param name="pScene"></param> |
@@ -1736,15 +1906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1736 | Scene pScene = avatar.Scene; | 1906 | Scene pScene = avatar.Scene; |
1737 | RegionInfo m_regionInfo = pScene.RegionInfo; | 1907 | RegionInfo m_regionInfo = pScene.RegionInfo; |
1738 | 1908 | ||
1739 | Border[] northBorders = pScene.NorthBorders.ToArray(); | ||
1740 | Border[] southBorders = pScene.SouthBorders.ToArray(); | ||
1741 | Border[] eastBorders = pScene.EastBorders.ToArray(); | ||
1742 | Border[] westBorders = pScene.WestBorders.ToArray(); | ||
1743 | |||
1744 | // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't | 1909 | // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't |
1745 | // clear what should be done with a "far view" given that megaregions already extended the | 1910 | // clear what should be done with a "far view" given that megaregions already extended the |
1746 | // view to include everything in the megaregion | 1911 | // view to include everything in the megaregion |
1747 | if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) | 1912 | if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
1748 | { | 1913 | { |
1749 | int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; | 1914 | int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; |
1750 | 1915 | ||
@@ -1762,27 +1927,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1762 | } | 1927 | } |
1763 | else | 1928 | else |
1764 | { | 1929 | { |
1765 | Vector2 extent = Vector2.Zero; | 1930 | Vector2 swCorner, neCorner; |
1766 | for (int i = 0; i < eastBorders.Length; i++) | 1931 | GetMegaregionViewRange(out swCorner, out neCorner); |
1767 | { | ||
1768 | extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; | ||
1769 | } | ||
1770 | for (int i = 0; i < northBorders.Length; i++) | ||
1771 | { | ||
1772 | extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; | ||
1773 | } | ||
1774 | |||
1775 | // Loss of fraction on purpose | ||
1776 | extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; | ||
1777 | extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; | ||
1778 | |||
1779 | int startX = (int)(pRegionLocX - 1) * (int)Constants.RegionSize; | ||
1780 | int startY = (int)(pRegionLocY - 1) * (int)Constants.RegionSize; | ||
1781 | 1932 | ||
1782 | int endX = ((int)pRegionLocX + (int)extent.X) * (int)Constants.RegionSize; | 1933 | List<GridRegion> neighbours |
1783 | int endY = ((int)pRegionLocY + (int)extent.Y) * (int)Constants.RegionSize; | 1934 | = pScene.GridService.GetRegionRange( |
1935 | m_regionInfo.ScopeID, | ||
1936 | (int)swCorner.X * (int)Constants.RegionSize, | ||
1937 | (int)neCorner.X * (int)Constants.RegionSize, | ||
1938 | (int)swCorner.Y * (int)Constants.RegionSize, | ||
1939 | (int)neCorner.Y * (int)Constants.RegionSize); | ||
1784 | 1940 | ||
1785 | List<GridRegion> neighbours = pScene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY); | ||
1786 | neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); | 1941 | neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); |
1787 | 1942 | ||
1788 | return neighbours; | 1943 | return neighbours; |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 9b78b3b..d372c0e 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
199 | 199 | ||
200 | public override void RemoveRegion(Scene scene) | 200 | public override void RemoveRegion(Scene scene) |
201 | { | 201 | { |
202 | base.AddRegion(scene); | 202 | base.RemoveRegion(scene); |
203 | 203 | ||
204 | if (m_Enabled) | 204 | if (m_Enabled) |
205 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); | 205 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); |
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 0276267..2b13a8b 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -189,6 +189,45 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
189 | case (int)HttpRequestConstants.HTTP_VERIFY_CERT: | 189 | case (int)HttpRequestConstants.HTTP_VERIFY_CERT: |
190 | htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); | 190 | htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); |
191 | break; | 191 | break; |
192 | |||
193 | case (int)HttpRequestConstants.HTTP_VERBOSE_THROTTLE: | ||
194 | |||
195 | // TODO implement me | ||
196 | break; | ||
197 | |||
198 | case (int)HttpRequestConstants.HTTP_CUSTOM_HEADER: | ||
199 | //Parameters are in pairs and custom header takes | ||
200 | //arguments in pairs so adjust for header marker. | ||
201 | ++i; | ||
202 | |||
203 | //Maximum of 8 headers are allowed based on the | ||
204 | //Second Life documentation for llHTTPRequest. | ||
205 | for (int count = 1; count <= 8; ++count) | ||
206 | { | ||
207 | //Not enough parameters remaining for a header? | ||
208 | if (parms.Length - i < 2) | ||
209 | break; | ||
210 | |||
211 | //Have we reached the end of the list of headers? | ||
212 | //End is marked by a string with a single digit. | ||
213 | //We already know we have at least one parameter | ||
214 | //so it is safe to do this check at top of loop. | ||
215 | if (Char.IsDigit(parms[i][0])) | ||
216 | break; | ||
217 | |||
218 | if (htc.HttpCustomHeaders == null) | ||
219 | htc.HttpCustomHeaders = new List<string>(); | ||
220 | |||
221 | htc.HttpCustomHeaders.Add(parms[i]); | ||
222 | htc.HttpCustomHeaders.Add(parms[i+1]); | ||
223 | |||
224 | i += 2; | ||
225 | } | ||
226 | break; | ||
227 | |||
228 | case (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE: | ||
229 | htc.HttpPragmaNoCache = (int.Parse(parms[i + 1]) != 0); | ||
230 | break; | ||
192 | } | 231 | } |
193 | } | 232 | } |
194 | } | 233 | } |
@@ -353,9 +392,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
353 | // public const int HTTP_METHOD = 0; | 392 | // public const int HTTP_METHOD = 0; |
354 | // public const int HTTP_MIMETYPE = 1; | 393 | // public const int HTTP_MIMETYPE = 1; |
355 | // public const int HTTP_VERIFY_CERT = 3; | 394 | // public const int HTTP_VERIFY_CERT = 3; |
395 | // public const int HTTP_VERBOSE_THROTTLE = 4; | ||
396 | // public const int HTTP_CUSTOM_HEADER = 5; | ||
397 | // public const int HTTP_PRAGMA_NO_CACHE = 6; | ||
356 | private bool _finished; | 398 | private bool _finished; |
357 | public bool Finished | 399 | public bool Finished |
358 | { | 400 | { |
359 | get { return _finished; } | 401 | get { return _finished; } |
360 | } | 402 | } |
361 | // public int HttpBodyMaxLen = 2048; // not implemented | 403 | // public int HttpBodyMaxLen = 2048; // not implemented |
@@ -367,9 +409,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
367 | public bool HttpVerifyCert = true; | 409 | public bool HttpVerifyCert = true; |
368 | public IWorkItemResult WorkItem = null; | 410 | public IWorkItemResult WorkItem = null; |
369 | 411 | ||
412 | //public bool HttpVerboseThrottle = true; // not implemented | ||
413 | public List<string> HttpCustomHeaders = null; | ||
414 | public bool HttpPragmaNoCache = true; | ||
415 | private Thread httpThread; | ||
416 | |||
370 | // Request info | 417 | // Request info |
371 | private UUID _itemID; | 418 | private UUID _itemID; |
372 | public UUID ItemID | 419 | public UUID ItemID |
373 | { | 420 | { |
374 | get { return _itemID; } | 421 | get { return _itemID; } |
375 | set { _itemID = value; } | 422 | set { _itemID = value; } |
@@ -385,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
385 | public string proxyexcepts; | 432 | public string proxyexcepts; |
386 | public string OutboundBody; | 433 | public string OutboundBody; |
387 | private UUID _reqID; | 434 | private UUID _reqID; |
388 | public UUID ReqID | 435 | public UUID ReqID |
389 | { | 436 | { |
390 | get { return _reqID; } | 437 | get { return _reqID; } |
391 | set { _reqID = value; } | 438 | set { _reqID = value; } |
@@ -434,20 +481,34 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
434 | Request.Method = HttpMethod; | 481 | Request.Method = HttpMethod; |
435 | Request.ContentType = HttpMIMEType; | 482 | Request.ContentType = HttpMIMEType; |
436 | 483 | ||
437 | if(!HttpVerifyCert) | 484 | if (!HttpVerifyCert) |
438 | { | 485 | { |
439 | // We could hijack Connection Group Name to identify | 486 | // We could hijack Connection Group Name to identify |
440 | // a desired security exception. But at the moment we'll use a dummy header instead. | 487 | // a desired security exception. But at the moment we'll use a dummy header instead. |
441 | Request.Headers.Add("NoVerifyCert", "true"); | 488 | Request.Headers.Add("NoVerifyCert", "true"); |
442 | } | 489 | } |
443 | if (proxyurl != null && proxyurl.Length > 0) | 490 | // else |
491 | // { | ||
492 | // Request.ConnectionGroupName="Verify"; | ||
493 | // } | ||
494 | if (!HttpPragmaNoCache) | ||
495 | { | ||
496 | Request.Headers.Add("Pragma", "no-cache"); | ||
497 | } | ||
498 | if (HttpCustomHeaders != null) | ||
444 | { | 499 | { |
445 | if (proxyexcepts != null && proxyexcepts.Length > 0) | 500 | for (int i = 0; i < HttpCustomHeaders.Count; i += 2) |
501 | Request.Headers.Add(HttpCustomHeaders[i], | ||
502 | HttpCustomHeaders[i+1]); | ||
503 | } | ||
504 | if (proxyurl != null && proxyurl.Length > 0) | ||
505 | { | ||
506 | if (proxyexcepts != null && proxyexcepts.Length > 0) | ||
446 | { | 507 | { |
447 | string[] elist = proxyexcepts.Split(';'); | 508 | string[] elist = proxyexcepts.Split(';'); |
448 | Request.Proxy = new WebProxy(proxyurl, true, elist); | 509 | Request.Proxy = new WebProxy(proxyurl, true, elist); |
449 | } | 510 | } |
450 | else | 511 | else |
451 | { | 512 | { |
452 | Request.Proxy = new WebProxy(proxyurl, true); | 513 | Request.Proxy = new WebProxy(proxyurl, true); |
453 | } | 514 | } |
@@ -460,7 +521,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
460 | Request.Headers[entry.Key] = entry.Value; | 521 | Request.Headers[entry.Key] = entry.Value; |
461 | 522 | ||
462 | // Encode outbound data | 523 | // Encode outbound data |
463 | if (OutboundBody.Length > 0) | 524 | if (OutboundBody.Length > 0) |
464 | { | 525 | { |
465 | byte[] data = Util.UTF8.GetBytes(OutboundBody); | 526 | byte[] data = Util.UTF8.GetBytes(OutboundBody); |
466 | 527 | ||
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 28db407..e434b2e 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -597,6 +597,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
597 | cdl.AddRow("LightFalloff", s.LightFalloff); | 597 | cdl.AddRow("LightFalloff", s.LightFalloff); |
598 | cdl.AddRow("LightIntensity", s.LightIntensity); | 598 | cdl.AddRow("LightIntensity", s.LightIntensity); |
599 | cdl.AddRow("LightRadius", s.LightRadius); | 599 | cdl.AddRow("LightRadius", s.LightRadius); |
600 | cdl.AddRow("Location (relative)", sop.RelativePosition); | ||
600 | cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); | 601 | cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); |
601 | cdl.AddRow("PathBegin", s.PathBegin); | 602 | cdl.AddRow("PathBegin", s.PathBegin); |
602 | cdl.AddRow("PathEnd", s.PathEnd); | 603 | cdl.AddRow("PathEnd", s.PathEnd); |
@@ -619,6 +620,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
619 | cdl.AddRow("ProjectionFocus", s.ProjectionFocus); | 620 | cdl.AddRow("ProjectionFocus", s.ProjectionFocus); |
620 | cdl.AddRow("ProjectionFOV", s.ProjectionFOV); | 621 | cdl.AddRow("ProjectionFOV", s.ProjectionFOV); |
621 | cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); | 622 | cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); |
623 | cdl.AddRow("Rotation (Relative)", sop.RotationOffset); | ||
624 | cdl.AddRow("Rotation (World)", sop.GetWorldRotation()); | ||
622 | cdl.AddRow("Scale", s.Scale); | 625 | cdl.AddRow("Scale", s.Scale); |
623 | cdl.AddRow( | 626 | cdl.AddRow( |
624 | "SculptData", | 627 | "SculptData", |
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index eaaf7a3..3c1247f 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | |||
@@ -54,6 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
54 | /// RezAttachments. This should only be called upon login on the first region. | 54 | /// RezAttachments. This should only be called upon login on the first region. |
55 | /// Attachment rezzings on crossings and TPs are done in a different way. | 55 | /// Attachment rezzings on crossings and TPs are done in a different way. |
56 | /// </summary> | 56 | /// </summary> |
57 | /// <remarks> | ||
58 | /// This is only actually necessary for viewers which do not have a current outfit folder (these viewers make | ||
59 | /// their own attachment calls on login) and agents which have attachments but no viewer (e.g. NPCs). | ||
60 | /// </remarks> | ||
57 | /// <param name="sp"></param> | 61 | /// <param name="sp"></param> |
58 | void RezAttachments(IScenePresence sp); | 62 | void RezAttachments(IScenePresence sp); |
59 | 63 | ||
@@ -77,14 +81,16 @@ namespace OpenSim.Region.Framework.Interfaces | |||
77 | void DeleteAttachmentsFromScene(IScenePresence sp, bool silent); | 81 | void DeleteAttachmentsFromScene(IScenePresence sp, bool silent); |
78 | 82 | ||
79 | /// <summary> | 83 | /// <summary> |
80 | /// Attach an object to an avatar | 84 | /// Attach an object to an avatar. |
81 | /// </summary> | 85 | /// </summary> |
82 | /// <param name="sp"></param> | 86 | /// <param name="sp"></param> |
83 | /// <param name="grp"></param> | 87 | /// <param name="grp"></param> |
84 | /// <param name="AttachmentPt"></param> | 88 | /// <param name="AttachmentPt"></param> |
85 | /// <param name="silent"></param> | 89 | /// <param name="silent"></param> |
90 | /// <param name="addToInventory">If true then add object to user inventory</param> | ||
91 | /// <param name="append">Append to attachment point rather than replace.</param> | ||
86 | /// <returns>true if the object was successfully attached, false otherwise</returns> | 92 | /// <returns>true if the object was successfully attached, false otherwise</returns> |
87 | bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp, bool append); | 93 | bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool addToInventory, bool append); |
88 | 94 | ||
89 | /// <summary> | 95 | /// <summary> |
90 | /// Rez an attachment from user inventory and change inventory status to match. | 96 | /// Rez an attachment from user inventory and change inventory status to match. |
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index de0f2a3..eb6c5ac 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs | |||
@@ -36,6 +36,9 @@ namespace OpenSim.Region.Framework.Interfaces | |||
36 | HTTP_MIMETYPE = 1, | 36 | HTTP_MIMETYPE = 1, |
37 | HTTP_BODY_MAXLENGTH = 2, | 37 | HTTP_BODY_MAXLENGTH = 2, |
38 | HTTP_VERIFY_CERT = 3, | 38 | HTTP_VERIFY_CERT = 3, |
39 | HTTP_VERBOSE_THROTTLE = 4, | ||
40 | HTTP_CUSTOM_HEADER = 5, | ||
41 | HTTP_PRAGMA_NO_CACHE = 6 | ||
39 | } | 42 | } |
40 | 43 | ||
41 | public interface IHttpRequestModule | 44 | public interface IHttpRequestModule |
diff --git a/OpenSim/Region/Framework/Scenes/Border.cs b/OpenSim/Region/Framework/Scenes/Border.cs index c6a6511..08c0c31 100644 --- a/OpenSim/Region/Framework/Scenes/Border.cs +++ b/OpenSim/Region/Framework/Scenes/Border.cs | |||
@@ -33,8 +33,7 @@ using OpenMetaverse; | |||
33 | namespace OpenSim.Region.Framework.Scenes | 33 | namespace OpenSim.Region.Framework.Scenes |
34 | { | 34 | { |
35 | public class Border | 35 | public class Border |
36 | { | 36 | { |
37 | |||
38 | /// <summary> | 37 | /// <summary> |
39 | /// Line perpendicular to the Direction Cardinal. Z value is the | 38 | /// Line perpendicular to the Direction Cardinal. Z value is the |
40 | /// </summary> | 39 | /// </summary> |
@@ -81,6 +80,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
81 | TriggerRegionY = triggerRegionY; | 80 | TriggerRegionY = triggerRegionY; |
82 | } | 81 | } |
83 | 82 | ||
83 | /// <summary> | ||
84 | /// Tests to see if the given position would cross this border. | ||
85 | /// </summary> | ||
86 | /// <returns></returns> | ||
84 | public bool TestCross(Vector3 position) | 87 | public bool TestCross(Vector3 position) |
85 | { | 88 | { |
86 | bool result = false; | 89 | bool result = false; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 357a94b..28fce53 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2644,7 +2644,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2644 | 2644 | ||
2645 | } | 2645 | } |
2646 | } | 2646 | } |
2647 | |||
2648 | 2647 | ||
2649 | return null; | 2648 | return null; |
2650 | } | 2649 | } |
@@ -2862,7 +2861,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2862 | // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); | 2861 | // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); |
2863 | 2862 | ||
2864 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 2863 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); |
2865 | 2864 | ||
2865 | // We must currently not resume scripts at this stage since AttachmentsModule does not have the | ||
2866 | // information that this is due to a teleport/border cross rather than an ordinary attachment. | ||
2867 | // We currently do this in Scene.MakeRootAgent() instead. | ||
2866 | if (AttachmentsModule != null) | 2868 | if (AttachmentsModule != null) |
2867 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true); | 2869 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true); |
2868 | } | 2870 | } |
@@ -2979,35 +2981,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2979 | m_eventManager.TriggerOnNewPresence(sp); | 2981 | m_eventManager.TriggerOnNewPresence(sp); |
2980 | 2982 | ||
2981 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; | 2983 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; |
2982 | |||
2983 | // The first agent upon login is a root agent by design. | ||
2984 | // For this agent we will have to rez the attachments. | ||
2985 | // All other AddNewClient calls find aCircuit.child to be true. | ||
2986 | if (aCircuit.child == false) | ||
2987 | { | ||
2988 | // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to | ||
2989 | // start the scripts again (since this is done in RezAttachments()). | ||
2990 | // XXX: This is convoluted. | ||
2991 | sp.IsChildAgent = false; | ||
2992 | sp.IsLoggingIn = true; | ||
2993 | |||
2994 | // We leave a 5 second pause before attempting to rez attachments to avoid a clash with | ||
2995 | // version 3 viewers that maybe doing their own attachment rezzing related to their current | ||
2996 | // outfit folder on startup. If these operations do clash, then the symptoms are invisible | ||
2997 | // attachments until one zooms in on the avatar. | ||
2998 | // | ||
2999 | // We do not pause if we are launching on the same thread anyway in order to avoid pointlessly | ||
3000 | // delaying any attachment related regression tests. | ||
3001 | if (AttachmentsModule != null) | ||
3002 | Util.FireAndForget( | ||
3003 | o => | ||
3004 | { | ||
3005 | if (Util.FireAndForgetMethod != FireAndForgetMethod.None) | ||
3006 | Thread.Sleep(5000); | ||
3007 | |||
3008 | AttachmentsModule.RezAttachments(sp); | ||
3009 | }); | ||
3010 | } | ||
3011 | } | 2984 | } |
3012 | else | 2985 | else |
3013 | { | 2986 | { |
@@ -4344,33 +4317,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
4344 | // } | 4317 | // } |
4345 | // } | 4318 | // } |
4346 | 4319 | ||
4347 | /// <summary> | 4320 | // /// <summary> |
4348 | /// Triggered when an agent crosses into this sim. Also happens on initial login. | 4321 | // /// Triggered when an agent crosses into this sim. Also happens on initial login. |
4349 | /// </summary> | 4322 | // /// </summary> |
4350 | /// <param name="agentID"></param> | 4323 | // /// <param name="agentID"></param> |
4351 | /// <param name="position"></param> | 4324 | // /// <param name="position"></param> |
4352 | /// <param name="isFlying"></param> | 4325 | // /// <param name="isFlying"></param> |
4353 | public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) | 4326 | // public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) |
4354 | { | 4327 | // { |
4355 | ScenePresence presence = GetScenePresence(agentID); | 4328 | // ScenePresence presence = GetScenePresence(agentID); |
4356 | if (presence != null) | 4329 | // if (presence != null) |
4357 | { | 4330 | // { |
4358 | try | 4331 | // try |
4359 | { | 4332 | // { |
4360 | presence.MakeRootAgent(position, isFlying); | 4333 | // presence.MakeRootAgent(position, isFlying); |
4361 | } | 4334 | // } |
4362 | catch (Exception e) | 4335 | // catch (Exception e) |
4363 | { | 4336 | // { |
4364 | m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); | 4337 | // m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); |
4365 | } | 4338 | // } |
4366 | } | 4339 | // } |
4367 | else | 4340 | // else |
4368 | { | 4341 | // { |
4369 | m_log.ErrorFormat( | 4342 | // m_log.ErrorFormat( |
4370 | "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", | 4343 | // "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", |
4371 | agentID, RegionInfo.RegionName); | 4344 | // agentID, RegionInfo.RegionName); |
4372 | } | 4345 | // } |
4373 | } | 4346 | // } |
4374 | 4347 | ||
4375 | /// <summary> | 4348 | /// <summary> |
4376 | /// We've got an update about an agent that sees into this region, | 4349 | /// We've got an update about an agent that sees into this region, |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c2f0792..42644dc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -3743,6 +3743,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3743 | /// <param name="events"></param> | 3743 | /// <param name="events"></param> |
3744 | public void SetScriptEvents(UUID scriptid, int events) | 3744 | public void SetScriptEvents(UUID scriptid, int events) |
3745 | { | 3745 | { |
3746 | // m_log.DebugFormat( | ||
3747 | // "[SCENE OBJECT PART]: Set script events for script with id {0} on {1}/{2} to {3} in {4}", | ||
3748 | // scriptid, Name, ParentGroup.Name, events, ParentGroup.Scene.Name); | ||
3749 | |||
3746 | // scriptEvents oldparts; | 3750 | // scriptEvents oldparts; |
3747 | lock (m_scriptEvents) | 3751 | lock (m_scriptEvents) |
3748 | { | 3752 | { |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5ed7b67..0ab267a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -456,9 +456,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
456 | { | 456 | { |
457 | m_pos = PhysicsActor.Position; | 457 | m_pos = PhysicsActor.Position; |
458 | 458 | ||
459 | //m_log.DebugFormat( | 459 | // m_log.DebugFormat( |
460 | // "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", | 460 | // "[SCENE PRESENCE]: Set position of {0} in {1} to {2} via getting AbsolutePosition!", |
461 | // m_pos, Name, Scene.RegionInfo.RegionName); | 461 | // Name, Scene.Name, m_pos); |
462 | } | 462 | } |
463 | else | 463 | else |
464 | { | 464 | { |
@@ -485,6 +485,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
485 | } | 485 | } |
486 | set | 486 | set |
487 | { | 487 | { |
488 | // m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} in {1} to {2}", Name, Scene.Name, value); | ||
489 | // Util.PrintCallStack(); | ||
490 | |||
488 | if (PhysicsActor != null) | 491 | if (PhysicsActor != null) |
489 | { | 492 | { |
490 | try | 493 | try |
@@ -938,8 +941,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
938 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | 941 | "[SCENE]: Upgrading child to root agent for {0} in {1}", |
939 | Name, m_scene.RegionInfo.RegionName); | 942 | Name, m_scene.RegionInfo.RegionName); |
940 | 943 | ||
941 | bool wasChild = IsChildAgent; | ||
942 | |||
943 | if (ParentUUID != UUID.Zero) | 944 | if (ParentUUID != UUID.Zero) |
944 | { | 945 | { |
945 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); | 946 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); |
@@ -972,6 +973,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
972 | IsLoggingIn = false; | 973 | IsLoggingIn = false; |
973 | } | 974 | } |
974 | 975 | ||
976 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
977 | |||
978 | IsChildAgent = false; | ||
975 | 979 | ||
976 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 980 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
977 | if (gm != null) | 981 | if (gm != null) |
@@ -1065,6 +1069,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1065 | else | 1069 | else |
1066 | AddToPhysicalScene(isFlying); | 1070 | AddToPhysicalScene(isFlying); |
1067 | 1071 | ||
1072 | // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a | ||
1073 | // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it | ||
1074 | // since it requires a physics actor to be present. If it is left any later, then physics appears to reset | ||
1075 | // the value to a negative position which does not trigger the border cross. | ||
1076 | // This may not be the best location for this. | ||
1077 | CheckForBorderCrossing(); | ||
1078 | |||
1068 | if (ForceFly) | 1079 | if (ForceFly) |
1069 | { | 1080 | { |
1070 | Flying = true; | 1081 | Flying = true; |
@@ -1085,22 +1096,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
1085 | // and it has already rezzed the attachments and started their scripts. | 1096 | // and it has already rezzed the attachments and started their scripts. |
1086 | // We do the following only for non-login agents, because their scripts | 1097 | // We do the following only for non-login agents, because their scripts |
1087 | // haven't started yet. | 1098 | // haven't started yet. |
1088 | lock (m_attachments) | 1099 | if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0) |
1100 | { | ||
1101 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | ||
1102 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1103 | if (Scene.AttachmentsModule != null) | ||
1104 | Util.FireAndForget( | ||
1105 | o => | ||
1106 | { | ||
1107 | // if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) | ||
1108 | // System.Threading.Thread.Sleep(7000); | ||
1109 | |||
1110 | Scene.AttachmentsModule.RezAttachments(this); | ||
1111 | }); | ||
1112 | } | ||
1113 | else | ||
1089 | { | 1114 | { |
1090 | if (wasChild && HasAttachments()) | 1115 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT |
1116 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1117 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1118 | // not transporting the required data. | ||
1119 | lock (m_attachments) | ||
1091 | { | 1120 | { |
1092 | m_log.DebugFormat( | 1121 | if (HasAttachments()) |
1093 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | 1122 | { |
1094 | 1123 | m_log.DebugFormat( | |
1095 | // Resume scripts | 1124 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); |
1096 | Util.FireAndForget(delegate(object x) { | 1125 | |
1097 | foreach (SceneObjectGroup sog in m_attachments) | 1126 | // Resume scripts |
1098 | { | 1127 | Util.FireAndForget(delegate(object x) { |
1099 | sog.ScheduleGroupForFullUpdate(); | 1128 | foreach (SceneObjectGroup sog in m_attachments) |
1100 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 1129 | { |
1101 | sog.ResumeScripts(); | 1130 | sog.ScheduleGroupForFullUpdate(); |
1102 | } | 1131 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); |
1103 | }); | 1132 | sog.ResumeScripts(); |
1133 | } | ||
1134 | }); | ||
1135 | } | ||
1104 | } | 1136 | } |
1105 | } | 1137 | } |
1106 | 1138 | ||
@@ -3121,6 +3153,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3121 | 3153 | ||
3122 | if (!IsInTransit) | 3154 | if (!IsInTransit) |
3123 | { | 3155 | { |
3156 | // m_log.DebugFormat( | ||
3157 | // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", | ||
3158 | // pos2, Name, Scene.Name); | ||
3159 | |||
3124 | // Checks if where it's headed exists a region | 3160 | // Checks if where it's headed exists a region |
3125 | bool needsTransit = false; | 3161 | bool needsTransit = false; |
3126 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) | 3162 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 8740f87..d56e39d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | |||
@@ -184,7 +184,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
184 | hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); | 184 | hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); |
185 | } | 185 | } |
186 | 186 | ||
187 | return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true, true) ? 1 : 0; | 187 | return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true, true) ? 1 : 0; |
188 | } | 188 | } |
189 | } | 189 | } |
190 | } | 190 | } |
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 5fb74b0..29b39e0 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs | |||
@@ -116,6 +116,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
116 | + "If teleport is true then some extra teleport debug information is logged.\n" | 116 | + "If teleport is true then some extra teleport debug information is logged.\n" |
117 | + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", | 117 | + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", |
118 | HandleDebugSceneSetCommand); | 118 | HandleDebugSceneSetCommand); |
119 | |||
120 | scene.AddCommand( | ||
121 | "Regions", | ||
122 | this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand); | ||
123 | } | ||
124 | |||
125 | private void HandleShowBordersCommand(string module, string[] args) | ||
126 | { | ||
127 | StringBuilder sb = new StringBuilder(); | ||
128 | sb.AppendFormat("Borders for {0}:\n", m_scene.Name); | ||
129 | |||
130 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
131 | cdt.AddColumn("Cross Direction", 15); | ||
132 | cdt.AddColumn("Line", 34); | ||
133 | cdt.AddColumn("Trigger Region", 14); | ||
134 | |||
135 | foreach (Border b in m_scene.NorthBorders) | ||
136 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
137 | |||
138 | foreach (Border b in m_scene.EastBorders) | ||
139 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
140 | |||
141 | foreach (Border b in m_scene.SouthBorders) | ||
142 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
143 | |||
144 | foreach (Border b in m_scene.WestBorders) | ||
145 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
146 | |||
147 | cdt.AddToStringBuilder(sb); | ||
148 | |||
149 | MainConsole.Instance.Output(sb.ToString()); | ||
119 | } | 150 | } |
120 | 151 | ||
121 | private void HandleDebugSceneGetCommand(string module, string[] args) | 152 | private void HandleDebugSceneGetCommand(string module, string[] args) |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index e208d3a..90c2d9c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -479,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject | |||
479 | // The character is out of the known/simulated area. | 479 | // The character is out of the known/simulated area. |
480 | // Force the avatar position to be within known. ScenePresence will use the position | 480 | // Force the avatar position to be within known. ScenePresence will use the position |
481 | // plus the velocity to decide if the avatar is moving out of the region. | 481 | // plus the velocity to decide if the avatar is moving out of the region. |
482 | RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); | 482 | RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); |
483 | DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); | 483 | DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); |
484 | return true; | 484 | return true; |
485 | } | 485 | } |
@@ -898,7 +898,7 @@ public sealed class BSCharacter : BSPhysObject | |||
898 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. | 898 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. |
899 | if (PositionSanityCheck(true)) | 899 | if (PositionSanityCheck(true)) |
900 | { | 900 | { |
901 | DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); | 901 | DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); |
902 | entprop.Position = _position; | 902 | entprop.Position = _position; |
903 | } | 903 | } |
904 | 904 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5549984..65df741 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -321,7 +321,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | internal void ProcessTypeChange(Vehicle pType) | 324 | public void ProcessTypeChange(Vehicle pType) |
325 | { | 325 | { |
326 | VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); | 326 | VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); |
327 | // Set Defaults For Type | 327 | // Set Defaults For Type |
@@ -1301,14 +1301,52 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1301 | // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. | 1301 | // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. |
1302 | public void ComputeAngularVerticalAttraction() | 1302 | public void ComputeAngularVerticalAttraction() |
1303 | { | 1303 | { |
1304 | |||
1304 | // If vertical attaction timescale is reasonable | 1305 | // If vertical attaction timescale is reasonable |
1305 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1306 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1306 | { | 1307 | { |
1308 | // Possible solution derived from a discussion at: | ||
1309 | // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no | ||
1310 | |||
1311 | // Create a rotation that is only the vehicle's rotation around Z | ||
1312 | Vector3 currentEuler = Vector3.Zero; | ||
1313 | VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); | ||
1314 | Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); | ||
1315 | |||
1316 | // Create the axis that is perpendicular to the up vector and the rotated up vector. | ||
1317 | Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); | ||
1318 | // Compute the angle between those to vectors. | ||
1319 | double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); | ||
1320 | // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical | ||
1321 | |||
1322 | // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. | ||
1323 | // TODO: add 'efficiency'. | ||
1324 | differenceAngle /= m_verticalAttractionTimescale; | ||
1325 | |||
1326 | // Create the quaterian representing the correction angle | ||
1327 | Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); | ||
1328 | |||
1329 | // Turn that quaternion into Euler values to make it into velocities to apply. | ||
1330 | Vector3 vertContributionV = Vector3.Zero; | ||
1331 | correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); | ||
1332 | vertContributionV *= -1f; | ||
1333 | |||
1334 | VehicleRotationalVelocity += vertContributionV; | ||
1335 | |||
1336 | VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", | ||
1337 | Prim.LocalID, | ||
1338 | differenceAxis, | ||
1339 | differenceAngle, | ||
1340 | correctionRotation, | ||
1341 | vertContributionV); | ||
1342 | |||
1343 | // =================================================================== | ||
1344 | /* | ||
1307 | Vector3 vertContributionV = Vector3.Zero; | 1345 | Vector3 vertContributionV = Vector3.Zero; |
1308 | Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG | 1346 | Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG |
1309 | 1347 | ||
1310 | // Take a vector pointing up and convert it from world to vehicle relative coords. | 1348 | // Take a vector pointing up and convert it from world to vehicle relative coords. |
1311 | Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; | 1349 | Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); |
1312 | 1350 | ||
1313 | // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) | 1351 | // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) |
1314 | // is now: | 1352 | // is now: |
@@ -1334,13 +1372,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1334 | // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. | 1372 | // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. |
1335 | // Correction happens over a number of seconds. | 1373 | // Correction happens over a number of seconds. |
1336 | Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG | 1374 | Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG |
1375 | |||
1376 | // The correction happens over the user's time period | ||
1337 | vertContributionV /= m_verticalAttractionTimescale; | 1377 | vertContributionV /= m_verticalAttractionTimescale; |
1338 | 1378 | ||
1339 | VehicleRotationalVelocity += vertContributionV; | 1379 | // Rotate the vehicle rotation to the world coordinates. |
1380 | VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); | ||
1340 | 1381 | ||
1341 | VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", | 1382 | VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", |
1342 | Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, | 1383 | Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, |
1343 | m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); | 1384 | m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); |
1385 | */ | ||
1344 | } | 1386 | } |
1345 | } | 1387 | } |
1346 | 1388 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index 92d62ff..ee77d6e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs | |||
@@ -180,11 +180,14 @@ public static class BSMaterials | |||
180 | // Use reflection to set the value in the attribute structure. | 180 | // Use reflection to set the value in the attribute structure. |
181 | private static void SetAttributeValue(int matType, string attribName, float val) | 181 | private static void SetAttributeValue(int matType, string attribName, float val) |
182 | { | 182 | { |
183 | // Get the current attribute values for this material | ||
183 | MaterialAttributes thisAttrib = Attributes[matType]; | 184 | MaterialAttributes thisAttrib = Attributes[matType]; |
185 | // Find the field for the passed attribute name (eg, find field named 'friction') | ||
184 | FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); | 186 | FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); |
185 | if (fieldInfo != null) | 187 | if (fieldInfo != null) |
186 | { | 188 | { |
187 | fieldInfo.SetValue(thisAttrib, val); | 189 | fieldInfo.SetValue(thisAttrib, val); |
190 | // Copy new attributes back to array -- since MaterialAttributes is 'struct', passed by value, not reference. | ||
188 | Attributes[matType] = thisAttrib; | 191 | Attributes[matType] = thisAttrib; |
189 | } | 192 | } |
190 | } | 193 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 4d89a88..385ed9e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -142,6 +142,14 @@ public static class BSParam | |||
142 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } | 142 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } |
143 | public static bool VehicleDebuggingEnabled { get; private set; } | 143 | public static bool VehicleDebuggingEnabled { get; private set; } |
144 | 144 | ||
145 | // Convex Hulls | ||
146 | public static int CSHullMaxDepthSplit { get; private set; } | ||
147 | public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; } | ||
148 | public static float CSHullConcavityThresholdPercent { get; private set; } | ||
149 | public static float CSHullVolumeConservationThresholdPercent { get; private set; } | ||
150 | public static int CSHullMaxVertices { get; private set; } | ||
151 | public static float CSHullMaxSkinWidth { get; private set; } | ||
152 | |||
145 | // Linkset implementation parameters | 153 | // Linkset implementation parameters |
146 | public static float LinksetImplementation { get; private set; } | 154 | public static float LinksetImplementation { get; private set; } |
147 | public static bool LinkConstraintUseFrameOffset { get; private set; } | 155 | public static bool LinkConstraintUseFrameOffset { get; private set; } |
@@ -195,10 +203,10 @@ public static class BSParam | |||
195 | public delegate void PSetOnObject<T>(BSScene scene, BSPhysObject obj); | 203 | public delegate void PSetOnObject<T>(BSScene scene, BSPhysObject obj); |
196 | public sealed class ParameterDefn<T> : ParameterDefnBase | 204 | public sealed class ParameterDefn<T> : ParameterDefnBase |
197 | { | 205 | { |
198 | T defaultValue; | 206 | private T defaultValue; |
199 | PSetValue<T> setter; | 207 | private PSetValue<T> setter; |
200 | PGetValue<T> getter; | 208 | private PGetValue<T> getter; |
201 | PSetOnObject<T> objectSet; | 209 | private PSetOnObject<T> objectSet; |
202 | public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue<T> pGetter, PSetValue<T> pSetter) | 210 | public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue<T> pGetter, PSetValue<T> pSetter) |
203 | : base(pName, pDesc) | 211 | : base(pName, pDesc) |
204 | { | 212 | { |
@@ -215,13 +223,23 @@ public static class BSParam | |||
215 | getter = pGetter; | 223 | getter = pGetter; |
216 | objectSet = pObjSetter; | 224 | objectSet = pObjSetter; |
217 | } | 225 | } |
226 | /* Wish I could simplify using this definition but CLR doesn't store references so closure around delegates of references won't work | ||
227 | public ParameterDefn(string pName, string pDesc, T pDefault, ref T loc) | ||
228 | : base(pName, pDesc) | ||
229 | { | ||
230 | defaultValue = pDefault; | ||
231 | setter = (s, v) => { loc = v; }; | ||
232 | getter = (s) => { return loc; }; | ||
233 | objectSet = null; | ||
234 | } | ||
235 | */ | ||
218 | public override void AssignDefault(BSScene s) | 236 | public override void AssignDefault(BSScene s) |
219 | { | 237 | { |
220 | setter(s, defaultValue); | 238 | setter(s, defaultValue); |
221 | } | 239 | } |
222 | public override string GetValue(BSScene s) | 240 | public override string GetValue(BSScene s) |
223 | { | 241 | { |
224 | return String.Format("{0}", getter(s)); | 242 | return getter(s).ToString(); |
225 | } | 243 | } |
226 | public override void SetValue(BSScene s, string valAsString) | 244 | public override void SetValue(BSScene s, string valAsString) |
227 | { | 245 | { |
@@ -244,6 +262,7 @@ public static class BSParam | |||
244 | try | 262 | try |
245 | { | 263 | { |
246 | T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString }); | 264 | T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString }); |
265 | // Store the parsed value | ||
247 | setter(s, setValue); | 266 | setter(s, setValue); |
248 | // s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue); | 267 | // s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue); |
249 | } | 268 | } |
@@ -463,7 +482,7 @@ public static class BSParam | |||
463 | (s) => { return TerrainImplementation; }, | 482 | (s) => { return TerrainImplementation; }, |
464 | (s,v) => { TerrainImplementation = v; } ), | 483 | (s,v) => { TerrainImplementation = v; } ), |
465 | new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , | 484 | new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , |
466 | 3, | 485 | 2, |
467 | (s) => { return TerrainMeshMagnification; }, | 486 | (s) => { return TerrainMeshMagnification; }, |
468 | (s,v) => { TerrainMeshMagnification = v; } ), | 487 | (s,v) => { TerrainMeshMagnification = v; } ), |
469 | new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" , | 488 | new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" , |
@@ -623,6 +642,31 @@ public static class BSParam | |||
623 | (s) => { return GlobalContactBreakingThreshold; }, | 642 | (s) => { return GlobalContactBreakingThreshold; }, |
624 | (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), | 643 | (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), |
625 | 644 | ||
645 | new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", | ||
646 | 7, | ||
647 | (s) => { return CSHullMaxDepthSplit; }, | ||
648 | (s,v) => { CSHullMaxDepthSplit = v; } ), | ||
649 | new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", | ||
650 | 2, | ||
651 | (s) => { return CSHullMaxDepthSplitForSimpleShapes; }, | ||
652 | (s,v) => { CSHullMaxDepthSplitForSimpleShapes = v; } ), | ||
653 | new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", | ||
654 | 5f, | ||
655 | (s) => { return CSHullConcavityThresholdPercent; }, | ||
656 | (s,v) => { CSHullConcavityThresholdPercent = v; } ), | ||
657 | new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", | ||
658 | 5f, | ||
659 | (s) => { return CSHullVolumeConservationThresholdPercent; }, | ||
660 | (s,v) => { CSHullVolumeConservationThresholdPercent = v; } ), | ||
661 | new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", | ||
662 | 32, | ||
663 | (s) => { return CSHullMaxVertices; }, | ||
664 | (s,v) => { CSHullMaxVertices = v; } ), | ||
665 | new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", | ||
666 | 0, | ||
667 | (s) => { return CSHullMaxSkinWidth; }, | ||
668 | (s,v) => { CSHullMaxSkinWidth = v; } ), | ||
669 | |||
626 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", | 670 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", |
627 | (float)BSLinkset.LinksetImplementation.Compound, | 671 | (float)BSLinkset.LinksetImplementation.Compound, |
628 | (s) => { return LinksetImplementation; }, | 672 | (s) => { return LinksetImplementation; }, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index f953c1e..6bb88c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -86,7 +86,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
86 | PhysBody = new BulletBody(localID); | 86 | PhysBody = new BulletBody(localID); |
87 | PhysShape = new BulletShape(); | 87 | PhysShape = new BulletShape(); |
88 | 88 | ||
89 | LastAssetBuildFailed = false; | 89 | PrimAssetState = PrimAssetCondition.Unknown; |
90 | 90 | ||
91 | // Default material type. Also sets Friction, Restitution and Density. | 91 | // Default material type. Also sets Friction, Restitution and Density. |
92 | SetMaterial((int)MaterialAttributes.Material.Wood); | 92 | SetMaterial((int)MaterialAttributes.Material.Wood); |
@@ -133,9 +133,13 @@ public abstract class BSPhysObject : PhysicsActor | |||
133 | // Reference to the physical shape (btCollisionShape) of this object | 133 | // Reference to the physical shape (btCollisionShape) of this object |
134 | public BulletShape PhysShape; | 134 | public BulletShape PhysShape; |
135 | 135 | ||
136 | // 'true' if the mesh's underlying asset failed to build. | 136 | // The physical representation of the prim might require an asset fetch. |
137 | // This will keep us from looping after the first time the build failed. | 137 | // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'. |
138 | public bool LastAssetBuildFailed { get; set; } | 138 | public enum PrimAssetCondition |
139 | { | ||
140 | Unknown, Waiting, Failed, Fetched | ||
141 | } | ||
142 | public PrimAssetCondition PrimAssetState { get; set; } | ||
139 | 143 | ||
140 | // The objects base shape information. Null if not a prim type shape. | 144 | // The objects base shape information. Null if not a prim type shape. |
141 | public PrimitiveBaseShape BaseShape { get; protected set; } | 145 | public PrimitiveBaseShape BaseShape { get; protected set; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2cbbe9a..6a5461a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -155,7 +155,7 @@ public class BSPrim : BSPhysObject | |||
155 | public override PrimitiveBaseShape Shape { | 155 | public override PrimitiveBaseShape Shape { |
156 | set { | 156 | set { |
157 | BaseShape = value; | 157 | BaseShape = value; |
158 | LastAssetBuildFailed = false; | 158 | PrimAssetState = PrimAssetCondition.Unknown; |
159 | ForceBodyShapeRebuild(false); | 159 | ForceBodyShapeRebuild(false); |
160 | } | 160 | } |
161 | } | 161 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 05c147d..220fbbc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -447,17 +447,10 @@ public sealed class BSShapeCollection : IDisposable | |||
447 | 447 | ||
448 | // If the prim attributes are simple, this could be a simple Bullet native shape | 448 | // If the prim attributes are simple, this could be a simple Bullet native shape |
449 | if (!haveShape | 449 | if (!haveShape |
450 | && nativeShapePossible | ||
450 | && pbs != null | 451 | && pbs != null |
451 | && !pbs.SculptEntry | 452 | && !pbs.SculptEntry |
452 | && nativeShapePossible | 453 | && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)) ) |
453 | && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) | ||
454 | || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | ||
455 | && pbs.ProfileHollow == 0 | ||
456 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | ||
457 | && pbs.PathBegin == 0 && pbs.PathEnd == 0 | ||
458 | && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 | ||
459 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | ||
460 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) | ||
461 | { | 454 | { |
462 | // Get the scale of any existing shape so we can see if the new shape is same native type and same size. | 455 | // Get the scale of any existing shape so we can see if the new shape is same native type and same size. |
463 | OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; | 456 | OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; |
@@ -508,6 +501,18 @@ public sealed class BSShapeCollection : IDisposable | |||
508 | return ret; | 501 | return ret; |
509 | } | 502 | } |
510 | 503 | ||
504 | // return 'true' if this shape description does not include any cutting or twisting. | ||
505 | private bool PrimHasNoCuts(PrimitiveBaseShape pbs) | ||
506 | { | ||
507 | return pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | ||
508 | && pbs.ProfileHollow == 0 | ||
509 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | ||
510 | && pbs.PathBegin == 0 && pbs.PathEnd == 0 | ||
511 | && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 | ||
512 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | ||
513 | && pbs.PathShearX == 0 && pbs.PathShearY == 0; | ||
514 | } | ||
515 | |||
511 | // return 'true' if the prim's shape was changed. | 516 | // return 'true' if the prim's shape was changed. |
512 | public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 517 | public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
513 | { | 518 | { |
@@ -518,7 +523,7 @@ public sealed class BSShapeCollection : IDisposable | |||
518 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) | 523 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) |
519 | { | 524 | { |
520 | // Update prim.BSShape to reference a hull of this shape. | 525 | // Update prim.BSShape to reference a hull of this shape. |
521 | ret = GetReferenceToHull(prim,shapeCallback); | 526 | ret = GetReferenceToHull(prim, shapeCallback); |
522 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 527 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
523 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 528 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
524 | } | 529 | } |
@@ -699,6 +704,7 @@ public sealed class BSShapeCollection : IDisposable | |||
699 | 704 | ||
700 | // See that hull shape exists in the physical world and update prim.BSShape. | 705 | // See that hull shape exists in the physical world and update prim.BSShape. |
701 | // We could be creating the hull because scale changed or whatever. | 706 | // We could be creating the hull because scale changed or whatever. |
707 | // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance. | ||
702 | private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 708 | private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
703 | { | 709 | { |
704 | BulletShape newShape; | 710 | BulletShape newShape; |
@@ -717,6 +723,7 @@ public sealed class BSShapeCollection : IDisposable | |||
717 | DereferenceShape(prim.PhysShape, shapeCallback); | 723 | DereferenceShape(prim.PhysShape, shapeCallback); |
718 | 724 | ||
719 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); | 725 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); |
726 | // It might not have been created if we're waiting for an asset. | ||
720 | newShape = VerifyMeshCreated(newShape, prim); | 727 | newShape = VerifyMeshCreated(newShape, prim); |
721 | 728 | ||
722 | ReferenceShape(newShape); | 729 | ReferenceShape(newShape); |
@@ -735,13 +742,13 @@ public sealed class BSShapeCollection : IDisposable | |||
735 | HullDesc hullDesc; | 742 | HullDesc hullDesc; |
736 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) | 743 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) |
737 | { | 744 | { |
738 | // If the hull shape already is created, just use it. | 745 | // If the hull shape already has been created, just use the one shared instance. |
739 | newShape = hullDesc.shape.Clone(); | 746 | newShape = hullDesc.shape.Clone(); |
740 | } | 747 | } |
741 | else | 748 | else |
742 | { | 749 | { |
743 | // Build a new hull in the physical world | 750 | // Build a new hull in the physical world. |
744 | // Pass true for physicalness as this creates some sort of bounding box which we don't need | 751 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed |
745 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false); | 752 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false); |
746 | if (meshData != null) | 753 | if (meshData != null) |
747 | { | 754 | { |
@@ -761,15 +768,35 @@ public sealed class BSShapeCollection : IDisposable | |||
761 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | 768 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); |
762 | } | 769 | } |
763 | 770 | ||
771 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | ||
772 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | ||
773 | { | ||
774 | // Simple primitive shapes we know are convex so they are better implemented with | ||
775 | // fewer hulls. | ||
776 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
777 | if (PrimHasNoCuts(pbs)) | ||
778 | { | ||
779 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
780 | } | ||
781 | } | ||
782 | |||
764 | // setup and do convex hull conversion | 783 | // setup and do convex hull conversion |
765 | m_hulls = new List<ConvexResult>(); | 784 | m_hulls = new List<ConvexResult>(); |
766 | DecompDesc dcomp = new DecompDesc(); | 785 | DecompDesc dcomp = new DecompDesc(); |
767 | dcomp.mIndices = convIndices; | 786 | dcomp.mIndices = convIndices; |
768 | dcomp.mVertices = convVertices; | 787 | dcomp.mVertices = convVertices; |
788 | dcomp.mDepth = maxDepthSplit; | ||
789 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
790 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
791 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
792 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
769 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | 793 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); |
770 | // create the hull into the _hulls variable | 794 | // create the hull into the _hulls variable |
771 | convexBuilder.process(dcomp); | 795 | convexBuilder.process(dcomp); |
772 | 796 | ||
797 | DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
798 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
799 | |||
773 | // Convert the vertices and indices for passing to unmanaged. | 800 | // Convert the vertices and indices for passing to unmanaged. |
774 | // The hull information is passed as a large floating point array. | 801 | // The hull information is passed as a large floating point array. |
775 | // The format is: | 802 | // The format is: |
@@ -904,58 +931,79 @@ public sealed class BSShapeCollection : IDisposable | |||
904 | if (newShape.HasPhysicalShape) | 931 | if (newShape.HasPhysicalShape) |
905 | return newShape; | 932 | return newShape; |
906 | 933 | ||
907 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset | 934 | // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been |
908 | if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) | 935 | // fetched but we end up here again, the meshing of the asset must have failed. |
936 | // Prevent trying to keep fetching the mesh by declaring failure. | ||
937 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | ||
938 | { | ||
939 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; | ||
940 | PhysicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", | ||
941 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); | ||
942 | } | ||
943 | else | ||
909 | { | 944 | { |
910 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); | 945 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset |
911 | // This will prevent looping through this code as we keep trying to get the failed shape | 946 | if (prim.BaseShape.SculptEntry |
912 | prim.LastAssetBuildFailed = true; | 947 | && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed |
948 | && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting | ||
949 | && prim.BaseShape.SculptTexture != OMV.UUID.Zero | ||
950 | ) | ||
951 | { | ||
952 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); | ||
953 | // Multiple requestors will know we're waiting for this asset | ||
954 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; | ||
913 | 955 | ||
914 | BSPhysObject xprim = prim; | 956 | BSPhysObject xprim = prim; |
915 | Util.FireAndForget(delegate | 957 | Util.FireAndForget(delegate |
916 | { | ||
917 | RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; | ||
918 | if (assetProvider != null) | ||
919 | { | 958 | { |
920 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. | 959 | RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; |
921 | assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) | 960 | if (assetProvider != null) |
922 | { | 961 | { |
923 | bool assetFound = false; // DEBUG DEBUG | 962 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. |
924 | string mismatchIDs = String.Empty; // DEBUG DEBUG | 963 | assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) |
925 | if (asset != null && yprim.BaseShape.SculptEntry) | ||
926 | { | 964 | { |
927 | if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) | 965 | bool assetFound = false; |
966 | string mismatchIDs = String.Empty; // DEBUG DEBUG | ||
967 | if (asset != null && yprim.BaseShape.SculptEntry) | ||
928 | { | 968 | { |
929 | yprim.BaseShape.SculptData = asset.Data; | 969 | if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) |
930 | // This will cause the prim to see that the filler shape is not the right | 970 | { |
931 | // one and try again to build the object. | 971 | yprim.BaseShape.SculptData = asset.Data; |
932 | // No race condition with the normal shape setting since the rebuild is at taint time. | 972 | // This will cause the prim to see that the filler shape is not the right |
933 | yprim.ForceBodyShapeRebuild(false /* inTaintTime */); | 973 | // one and try again to build the object. |
934 | assetFound = true; | 974 | // No race condition with the normal shape setting since the rebuild is at taint time. |
975 | yprim.ForceBodyShapeRebuild(false /* inTaintTime */); | ||
976 | assetFound = true; | ||
977 | } | ||
978 | else | ||
979 | { | ||
980 | mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; | ||
981 | } | ||
935 | } | 982 | } |
983 | if (assetFound) | ||
984 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; | ||
936 | else | 985 | else |
937 | { | 986 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; |
938 | mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; | 987 | DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", |
939 | } | 988 | yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); |
940 | } | ||
941 | DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", | ||
942 | yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); | ||
943 | 989 | ||
944 | }); | 990 | }); |
945 | } | 991 | } |
946 | else | 992 | else |
947 | { | 993 | { |
948 | PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", | 994 | xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; |
949 | LogHeader, PhysicsScene.Name); | 995 | PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", |
950 | } | 996 | LogHeader, PhysicsScene.Name); |
951 | }); | 997 | } |
952 | } | 998 | }); |
953 | else | 999 | } |
954 | { | 1000 | else |
955 | if (prim.LastAssetBuildFailed) | ||
956 | { | 1001 | { |
957 | PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", | 1002 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) |
958 | LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); | 1003 | { |
1004 | PhysicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", | ||
1005 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); | ||
1006 | } | ||
959 | } | 1007 | } |
960 | } | 1008 | } |
961 | 1009 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index a60946d..b2fb835 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -132,6 +132,7 @@ public sealed class BSTerrainManager : IDisposable | |||
132 | // safe to call Bullet in real time. We hope no one is moving prims around yet. | 132 | // safe to call Bullet in real time. We hope no one is moving prims around yet. |
133 | public void CreateInitialGroundPlaneAndTerrain() | 133 | public void CreateInitialGroundPlaneAndTerrain() |
134 | { | 134 | { |
135 | DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); | ||
135 | // The ground plane is here to catch things that are trying to drop to negative infinity | 136 | // The ground plane is here to catch things that are trying to drop to negative infinity |
136 | BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); | 137 | BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); |
137 | m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, | 138 | m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, |
@@ -145,14 +146,18 @@ public sealed class BSTerrainManager : IDisposable | |||
145 | m_groundPlane.collisionType = CollisionType.Groundplane; | 146 | m_groundPlane.collisionType = CollisionType.Groundplane; |
146 | m_groundPlane.ApplyCollisionMask(PhysicsScene); | 147 | m_groundPlane.ApplyCollisionMask(PhysicsScene); |
147 | 148 | ||
148 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. | ||
149 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); | 149 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); |
150 | m_terrains.Add(Vector3.Zero, initialTerrain); | 150 | lock (m_terrains) |
151 | { | ||
152 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. | ||
153 | m_terrains.Add(Vector3.Zero, initialTerrain); | ||
154 | } | ||
151 | } | 155 | } |
152 | 156 | ||
153 | // Release all the terrain structures we might have allocated | 157 | // Release all the terrain structures we might have allocated |
154 | public void ReleaseGroundPlaneAndTerrain() | 158 | public void ReleaseGroundPlaneAndTerrain() |
155 | { | 159 | { |
160 | DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); | ||
156 | if (m_groundPlane.HasPhysicalBody) | 161 | if (m_groundPlane.HasPhysicalBody) |
157 | { | 162 | { |
158 | if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) | 163 | if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) |
@@ -193,11 +198,16 @@ public sealed class BSTerrainManager : IDisposable | |||
193 | // the terrain is added to our parent | 198 | // the terrain is added to our parent |
194 | if (MegaRegionParentPhysicsScene is BSScene) | 199 | if (MegaRegionParentPhysicsScene is BSScene) |
195 | { | 200 | { |
196 | DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", | 201 | DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", BSScene.DetailLogZero, m_worldOffset, m_worldMax); |
197 | BSScene.DetailLogZero, m_worldOffset, m_worldMax); | 202 | // This looks really odd but this region is passing its terrain to its mega-region root region |
198 | ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( | 203 | // and the creation of the terrain must happen on the root region's taint thread and not |
199 | BSScene.CHILDTERRAIN_ID, localHeightMap, | 204 | // my taint thread. |
200 | m_worldOffset, m_worldOffset + DefaultRegionSize, true); | 205 | ((BSScene)MegaRegionParentPhysicsScene).PostTaintObject("TerrainManager.SetTerrain.Mega-" + m_worldOffset.ToString(), 0, delegate() |
206 | { | ||
207 | ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( | ||
208 | BSScene.CHILDTERRAIN_ID, localHeightMap, | ||
209 | m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); | ||
210 | }); | ||
201 | } | 211 | } |
202 | } | 212 | } |
203 | else | 213 | else |
@@ -206,16 +216,16 @@ public sealed class BSTerrainManager : IDisposable | |||
206 | DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); | 216 | DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); |
207 | 217 | ||
208 | UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, | 218 | UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, |
209 | m_worldOffset, m_worldOffset + DefaultRegionSize, true); | 219 | m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); |
210 | } | 220 | } |
211 | }); | 221 | }); |
212 | } | 222 | } |
213 | 223 | ||
214 | // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain | 224 | // If called for terrain has has not been previously allocated, a new terrain will be built |
215 | // based on the passed information. The 'id' should be either the terrain id or | 225 | // based on the passed information. The 'id' should be either the terrain id or |
216 | // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. | 226 | // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. |
217 | // The latter feature is for creating child terrains for mega-regions. | 227 | // The latter feature is for creating child terrains for mega-regions. |
218 | // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new | 228 | // If there is an existing terrain body, a new |
219 | // terrain shape is created and added to the body. | 229 | // terrain shape is created and added to the body. |
220 | // This call is most often used to update the heightMap and parameters of the terrain. | 230 | // This call is most often used to update the heightMap and parameters of the terrain. |
221 | // (The above does suggest that some simplification/refactoring is in order.) | 231 | // (The above does suggest that some simplification/refactoring is in order.) |
@@ -223,8 +233,8 @@ public sealed class BSTerrainManager : IDisposable | |||
223 | private void UpdateTerrain(uint id, float[] heightMap, | 233 | private void UpdateTerrain(uint id, float[] heightMap, |
224 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) | 234 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) |
225 | { | 235 | { |
226 | DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", | 236 | DetailLog("{0},BSTerrainManager.UpdateTerrain,call,id={1},minC={2},maxC={3},inTaintTime={4}", |
227 | BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); | 237 | BSScene.DetailLogZero, id, minCoords, maxCoords, inTaintTime); |
228 | 238 | ||
229 | // Find high and low points of passed heightmap. | 239 | // Find high and low points of passed heightmap. |
230 | // The min and max passed in is usually the area objects can be in (maximum | 240 | // The min and max passed in is usually the area objects can be in (maximum |
@@ -253,7 +263,7 @@ public sealed class BSTerrainManager : IDisposable | |||
253 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) | 263 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) |
254 | { | 264 | { |
255 | // There is already a terrain in this spot. Free the old and build the new. | 265 | // There is already a terrain in this spot. Free the old and build the new. |
256 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | 266 | DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", |
257 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | 267 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); |
258 | 268 | ||
259 | // Remove old terrain from the collection | 269 | // Remove old terrain from the collection |
@@ -292,7 +302,7 @@ public sealed class BSTerrainManager : IDisposable | |||
292 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) | 302 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) |
293 | newTerrainID = ++m_terrainCount; | 303 | newTerrainID = ++m_terrainCount; |
294 | 304 | ||
295 | DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", | 305 | DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", |
296 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); | 306 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); |
297 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); | 307 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); |
298 | m_terrains.Add(terrainRegionBase, newTerrainPhys); | 308 | m_terrains.Add(terrainRegionBase, newTerrainPhys); |
@@ -343,37 +353,35 @@ public sealed class BSTerrainManager : IDisposable | |||
343 | { | 353 | { |
344 | Vector3 ret = pPos; | 354 | Vector3 ret = pPos; |
345 | 355 | ||
356 | // First, base addresses are never negative so correct for that possible problem. | ||
357 | if (ret.X < 0f || ret.Y < 0f) | ||
358 | { | ||
359 | ret.X = Util.Clamp<float>(ret.X, 0f, 1000000f); | ||
360 | ret.Y = Util.Clamp<float>(ret.Y, 0f, 1000000f); | ||
361 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}", | ||
362 | BSScene.DetailLogZero, pPos, ret); | ||
363 | } | ||
364 | |||
346 | // Can't do this function if we don't know about any terrain. | 365 | // Can't do this function if we don't know about any terrain. |
347 | if (m_terrains.Count == 0) | 366 | if (m_terrains.Count == 0) |
348 | return ret; | 367 | return ret; |
349 | 368 | ||
350 | int loopPrevention = 5; | 369 | int loopPrevention = 10; |
351 | Vector3 terrainBaseXYZ; | 370 | Vector3 terrainBaseXYZ; |
352 | BSTerrainPhys physTerrain; | 371 | BSTerrainPhys physTerrain; |
353 | while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ)) | 372 | while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ)) |
354 | { | 373 | { |
355 | // The passed position is not within a known terrain area. | 374 | // The passed position is not within a known terrain area. |
375 | // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. | ||
356 | 376 | ||
357 | // First, base addresses are never negative so correct for that possible problem. | 377 | // Must be off the top of a region. Find an adjacent region to move into. |
358 | if (ret.X < 0f || ret.Y < 0f) | 378 | Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); |
359 | { | 379 | |
360 | if (ret.X < 0f) | 380 | ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X)); |
361 | ret.X = 0f; | 381 | ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y)); |
362 | if (ret.Y < 0f) | 382 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", |
363 | ret.Y = 0f; | 383 | BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); |
364 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}", | ||
365 | BSScene.DetailLogZero, pPos, ret); | ||
366 | } | ||
367 | else | ||
368 | { | ||
369 | // Must be off the top of a region. Find an adjacent region to move into. | ||
370 | Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); | ||
371 | 384 | ||
372 | ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X); | ||
373 | ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y); | ||
374 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", | ||
375 | BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); | ||
376 | } | ||
377 | if (loopPrevention-- < 0f) | 385 | if (loopPrevention-- < 0f) |
378 | { | 386 | { |
379 | // The 'while' is a little dangerous so this prevents looping forever if the | 387 | // The 'while' is a little dangerous so this prevents looping forever if the |
@@ -383,6 +391,7 @@ public sealed class BSTerrainManager : IDisposable | |||
383 | break; | 391 | break; |
384 | } | 392 | } |
385 | } | 393 | } |
394 | |||
386 | return ret; | 395 | return ret; |
387 | } | 396 | } |
388 | 397 | ||
@@ -479,11 +488,20 @@ public sealed class BSTerrainManager : IDisposable | |||
479 | private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase) | 488 | private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase) |
480 | { | 489 | { |
481 | Vector3 ret = pTerrainBase; | 490 | Vector3 ret = pTerrainBase; |
491 | |||
492 | // Can't do this function if we don't know about any terrain. | ||
493 | if (m_terrains.Count == 0) | ||
494 | return ret; | ||
495 | |||
496 | // Just some sanity | ||
497 | ret.X = Util.Clamp<float>(ret.X, 0f, 1000000f); | ||
498 | ret.Y = Util.Clamp<float>(ret.Y, 0f, 1000000f); | ||
482 | ret.Z = 0f; | 499 | ret.Z = 0f; |
500 | |||
483 | lock (m_terrains) | 501 | lock (m_terrains) |
484 | { | 502 | { |
485 | // Once down to the <0,0> region, we have to be done. | 503 | // Once down to the <0,0> region, we have to be done. |
486 | while (ret.X > 0f && ret.Y > 0f) | 504 | while (ret.X > 0f || ret.Y > 0f) |
487 | { | 505 | { |
488 | if (ret.X > 0f) | 506 | if (ret.X > 0f) |
489 | { | 507 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index a9cd8a1..2ce1513 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | |||
@@ -98,20 +98,20 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
98 | if (!meshCreationSuccess) | 98 | if (!meshCreationSuccess) |
99 | { | 99 | { |
100 | // DISASTER!! | 100 | // DISASTER!! |
101 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); | 101 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID); |
102 | PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); | 102 | PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); |
103 | // Something is very messed up and a crash is in our future. | 103 | // Something is very messed up and a crash is in our future. |
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | 106 | ||
107 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", | 107 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}", |
108 | ID, indicesCount, indices.Length, verticesCount, vertices.Length); | 108 | BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length); |
109 | 109 | ||
110 | m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices); | 110 | m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices); |
111 | if (!m_terrainShape.HasPhysicalShape) | 111 | if (!m_terrainShape.HasPhysicalShape) |
112 | { | 112 | { |
113 | // DISASTER!! | 113 | // DISASTER!! |
114 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); | 114 | PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID); |
115 | PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); | 115 | PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); |
116 | // Something is very messed up and a crash is in our future. | 116 | // Something is very messed up and a crash is in our future. |
117 | return; | 117 | return; |
@@ -151,7 +151,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
151 | 151 | ||
152 | if (BSParam.UseSingleSidedMeshes) | 152 | if (BSParam.UseSingleSidedMeshes) |
153 | { | 153 | { |
154 | PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial", id); | 154 | PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id); |
155 | PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); | 155 | PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 905540d..7127c73 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -415,18 +415,17 @@ namespace OpenSim.Region.RegionCombinerModule | |||
415 | */ | 415 | */ |
416 | #endregion | 416 | #endregion |
417 | 417 | ||
418 | // If we're one region over +x y | 418 | // If we're one region over +x y (i.e. root region is to the west) |
419 | //xxx | 419 | //xxx |
420 | //xxy | 420 | //xxy |
421 | //xxx | 421 | //xxx |
422 | |||
423 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) | 422 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) |
424 | { | 423 | { |
425 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); | 424 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
426 | break; | 425 | break; |
427 | } | 426 | } |
428 | 427 | ||
429 | // If we're one region over x +y | 428 | // If we're one region over x +y (i.e. root region is to the south) |
430 | //xyx | 429 | //xyx |
431 | //xxx | 430 | //xxx |
432 | //xxx | 431 | //xxx |
@@ -436,7 +435,7 @@ namespace OpenSim.Region.RegionCombinerModule | |||
436 | break; | 435 | break; |
437 | } | 436 | } |
438 | 437 | ||
439 | // If we're one region over +x +y | 438 | // If we're one region over +x +y (i.e. root region is to the south-west) |
440 | //xxy | 439 | //xxy |
441 | //xxx | 440 | //xxx |
442 | //xxx | 441 | //xxx |
@@ -646,7 +645,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
646 | { | 645 | { |
647 | if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) | 646 | if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) |
648 | { | 647 | { |
649 | |||
650 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; | 648 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; |
651 | 649 | ||
652 | lock (rootConn.RegionScene.NorthBorders) | 650 | lock (rootConn.RegionScene.NorthBorders) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f677cdf..bc35272 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -71,6 +71,7 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | |||
71 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 71 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
72 | using System.Reflection; | 72 | using System.Reflection; |
73 | using Timer = System.Timers.Timer; | 73 | using Timer = System.Timers.Timer; |
74 | using System.Linq; | ||
74 | using PermissionMask = OpenSim.Framework.PermissionMask; | 75 | using PermissionMask = OpenSim.Framework.PermissionMask; |
75 | 76 | ||
76 | namespace OpenSim.Region.ScriptEngine.Shared.Api | 77 | namespace OpenSim.Region.ScriptEngine.Shared.Api |
@@ -96,8 +97,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
96 | /// <summary> | 97 | /// <summary> |
97 | /// Used for script sleeps when we are using co-operative script termination. | 98 | /// Used for script sleeps when we are using co-operative script termination. |
98 | /// </summary> | 99 | /// </summary> |
99 | /// <remarks>null if co-operative script termination is not active</remarks> | 100 | /// <remarks>null if co-operative script termination is not active</remarks> |
100 | WaitHandle m_coopSleepHandle; | 101 | WaitHandle m_coopSleepHandle; |
101 | 102 | ||
102 | /// <summary> | 103 | /// <summary> |
103 | /// The item that hosts this script | 104 | /// The item that hosts this script |
@@ -150,6 +151,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
150 | {"TURNLEFT", "Turning Left"}, | 151 | {"TURNLEFT", "Turning Left"}, |
151 | {"TURNRIGHT", "Turning Right"} | 152 | {"TURNRIGHT", "Turning Right"} |
152 | }; | 153 | }; |
154 | //An array of HTTP/1.1 headers that are not allowed to be used | ||
155 | //as custom headers by llHTTPRequest. | ||
156 | private string[] HttpStandardHeaders = | ||
157 | { | ||
158 | "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", | ||
159 | "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control", | ||
160 | "Connection", "Content-Encoding", "Content-Language", | ||
161 | "Content-Length", "Content-Location", "Content-MD5", | ||
162 | "Content-Range", "Content-Type", "Date", "ETag", "Expect", | ||
163 | "Expires", "From", "Host", "If-Match", "If-Modified-Since", | ||
164 | "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", | ||
165 | "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate", | ||
166 | "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server", | ||
167 | "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent", | ||
168 | "Vary", "Via", "Warning", "WWW-Authenticate" | ||
169 | }; | ||
153 | 170 | ||
154 | public void Initialize( | 171 | public void Initialize( |
155 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | 172 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) |
@@ -391,7 +408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
391 | /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number | 408 | /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number |
392 | /// of entities, then the entity which corresponds to that linknum is returned. | 409 | /// of entities, then the entity which corresponds to that linknum is returned. |
393 | /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then | 410 | /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then |
394 | /// null is returned. | 411 | /// null is returned. |
395 | /// </param> | 412 | /// </param> |
396 | public ISceneEntity GetLinkEntity(int linknum) | 413 | public ISceneEntity GetLinkEntity(int linknum) |
397 | { | 414 | { |
@@ -1750,7 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1750 | if (tex.FaceTextures[i] != null) | 1767 | if (tex.FaceTextures[i] != null) |
1751 | { | 1768 | { |
1752 | tex.FaceTextures[i].Shiny = sval; | 1769 | tex.FaceTextures[i].Shiny = sval; |
1753 | tex.FaceTextures[i].Bump = bump;; | 1770 | tex.FaceTextures[i].Bump = bump; |
1754 | } | 1771 | } |
1755 | tex.DefaultTexture.Shiny = sval; | 1772 | tex.DefaultTexture.Shiny = sval; |
1756 | tex.DefaultTexture.Bump = bump; | 1773 | tex.DefaultTexture.Bump = bump; |
@@ -1873,7 +1890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1873 | texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); | 1890 | texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); |
1874 | tex.DefaultTexture.RGBA = texcolor; | 1891 | tex.DefaultTexture.RGBA = texcolor; |
1875 | } | 1892 | } |
1876 | 1893 | ||
1877 | part.UpdateTextureEntry(tex.GetBytes()); | 1894 | part.UpdateTextureEntry(tex.GetBytes()); |
1878 | return; | 1895 | return; |
1879 | } | 1896 | } |
@@ -1996,7 +2013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1996 | rgb.x = texcolor.R; | 2013 | rgb.x = texcolor.R; |
1997 | rgb.y = texcolor.G; | 2014 | rgb.y = texcolor.G; |
1998 | rgb.z = texcolor.B; | 2015 | rgb.z = texcolor.B; |
1999 | 2016 | ||
2000 | return rgb; | 2017 | return rgb; |
2001 | } | 2018 | } |
2002 | else | 2019 | else |
@@ -2038,12 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2038 | 2055 | ||
2039 | UUID textureID = new UUID(); | 2056 | UUID textureID = new UUID(); |
2040 | 2057 | ||
2041 | textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); | 2058 | textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); |
2042 | if (textureID == UUID.Zero) | 2059 | if (textureID == UUID.Zero) |
2043 | { | 2060 | { |
2044 | if (!UUID.TryParse(texture, out textureID)) | 2061 | if (!UUID.TryParse(texture, out textureID)) |
2045 | return; | 2062 | return; |
2046 | } | 2063 | } |
2047 | 2064 | ||
2048 | Primitive.TextureEntry tex = part.Shape.Textures; | 2065 | Primitive.TextureEntry tex = part.Shape.Textures; |
2049 | 2066 | ||
@@ -2249,7 +2266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2249 | // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. | 2266 | // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. |
2250 | // | 2267 | // |
2251 | // This workaround is to prevent silent failure of this function. | 2268 | // This workaround is to prevent silent failure of this function. |
2252 | // According to the specification on the SL Wiki, providing a position outside of the | 2269 | // According to the specification on the SL Wiki, providing a position outside of the |
2253 | if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) | 2270 | if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) |
2254 | { | 2271 | { |
2255 | return 0; | 2272 | return 0; |
@@ -2484,7 +2501,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2484 | { | 2501 | { |
2485 | return llGetRootRotation(); | 2502 | return llGetRootRotation(); |
2486 | } | 2503 | } |
2487 | 2504 | ||
2488 | m_host.AddScriptLPS(1); | 2505 | m_host.AddScriptLPS(1); |
2489 | Quaternion q = m_host.GetWorldRotation(); | 2506 | Quaternion q = m_host.GetWorldRotation(); |
2490 | 2507 | ||
@@ -3317,7 +3334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3317 | 3334 | ||
3318 | if (!UUID.TryParse(id, out objectID)) | 3335 | if (!UUID.TryParse(id, out objectID)) |
3319 | objectID = UUID.Zero; | 3336 | objectID = UUID.Zero; |
3320 | 3337 | ||
3321 | if (objectID == UUID.Zero && name == "") | 3338 | if (objectID == UUID.Zero && name == "") |
3322 | return; | 3339 | return; |
3323 | 3340 | ||
@@ -3527,19 +3544,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3527 | msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; | 3544 | msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; |
3528 | 3545 | ||
3529 | Vector3 pos = m_host.AbsolutePosition; | 3546 | Vector3 pos = m_host.AbsolutePosition; |
3530 | msg.binaryBucket | 3547 | msg.binaryBucket |
3531 | = Util.StringToBytes256( | 3548 | = Util.StringToBytes256( |
3532 | "{0}/{1}/{2}/{3}", | 3549 | "{0}/{1}/{2}/{3}", |
3533 | World.RegionInfo.RegionName, | 3550 | World.RegionInfo.RegionName, |
3534 | (int)Math.Floor(pos.X), | 3551 | (int)Math.Floor(pos.X), |
3535 | (int)Math.Floor(pos.Y), | 3552 | (int)Math.Floor(pos.Y), |
3536 | (int)Math.Floor(pos.Z)); | 3553 | (int)Math.Floor(pos.Z)); |
3537 | 3554 | ||
3538 | if (m_TransferModule != null) | 3555 | if (m_TransferModule != null) |
3539 | { | 3556 | { |
3540 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); | 3557 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); |
3541 | } | 3558 | } |
3542 | 3559 | ||
3543 | ScriptSleep(2000); | 3560 | ScriptSleep(2000); |
3544 | } | 3561 | } |
3545 | 3562 | ||
@@ -3664,7 +3681,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3664 | public void llRotLookAt(LSL_Rotation target, double strength, double damping) | 3681 | public void llRotLookAt(LSL_Rotation target, double strength, double damping) |
3665 | { | 3682 | { |
3666 | m_host.AddScriptLPS(1); | 3683 | m_host.AddScriptLPS(1); |
3667 | 3684 | ||
3668 | // Per discussion with Melanie, for non-physical objects llLookAt appears to simply | 3685 | // Per discussion with Melanie, for non-physical objects llLookAt appears to simply |
3669 | // set the rotation of the object, copy that behavior | 3686 | // set the rotation of the object, copy that behavior |
3670 | PhysicsActor pa = m_host.PhysActor; | 3687 | PhysicsActor pa = m_host.PhysActor; |
@@ -5458,7 +5475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5458 | // SL spits out an empty string for types other than key & string | 5475 | // SL spits out an empty string for types other than key & string |
5459 | // At the time of patching, LSL_Key is currently LSL_String, | 5476 | // At the time of patching, LSL_Key is currently LSL_String, |
5460 | // so the OR check may be a little redundant, but it's being done | 5477 | // so the OR check may be a little redundant, but it's being done |
5461 | // for completion and should LSL_Key ever be implemented | 5478 | // for completion and should LSL_Key ever be implemented |
5462 | // as it's own struct | 5479 | // as it's own struct |
5463 | else if (!(src.Data[index] is LSL_String || | 5480 | else if (!(src.Data[index] is LSL_String || |
5464 | src.Data[index] is LSL_Key || | 5481 | src.Data[index] is LSL_Key || |
@@ -5595,8 +5612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5595 | { | 5612 | { |
5596 | m_host.AddScriptLPS(1); | 5613 | m_host.AddScriptLPS(1); |
5597 | 5614 | ||
5598 | return string.Join(", ", | 5615 | return string.Join(", ", |
5599 | (new List<object>(src.Data)).ConvertAll<string>(o => | 5616 | (new List<object>(src.Data)).ConvertAll<string>(o => |
5600 | { | 5617 | { |
5601 | return o.ToString(); | 5618 | return o.ToString(); |
5602 | }).ToArray()); | 5619 | }).ToArray()); |
@@ -6700,7 +6717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6700 | SetParticleSystem(m_host, rules); | 6717 | SetParticleSystem(m_host, rules); |
6701 | } | 6718 | } |
6702 | 6719 | ||
6703 | private void SetParticleSystem(SceneObjectPart part, LSL_List rules) | 6720 | private void SetParticleSystem(SceneObjectPart part, LSL_List rules) |
6704 | { | 6721 | { |
6705 | if (rules.Length == 0) | 6722 | if (rules.Length == 0) |
6706 | { | 6723 | { |
@@ -6937,7 +6954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6937 | m_host.OwnerID, m_host.Name, destID, | 6954 | m_host.OwnerID, m_host.Name, destID, |
6938 | (byte)InstantMessageDialog.TaskInventoryOffered, | 6955 | (byte)InstantMessageDialog.TaskInventoryOffered, |
6939 | false, string.Format("'{0}'", category), | 6956 | false, string.Format("'{0}'", category), |
6940 | // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 | 6957 | // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 |
6941 | // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), | 6958 | // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), |
6942 | folderID, false, pos, | 6959 | folderID, false, pos, |
6943 | bucket, false); | 6960 | bucket, false); |
@@ -7056,12 +7073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7056 | public LSL_String llAvatarOnLinkSitTarget(int linknum) | 7073 | public LSL_String llAvatarOnLinkSitTarget(int linknum) |
7057 | { | 7074 | { |
7058 | m_host.AddScriptLPS(1); | 7075 | m_host.AddScriptLPS(1); |
7059 | if(linknum == ScriptBaseClass.LINK_SET || | 7076 | if(linknum == ScriptBaseClass.LINK_SET || |
7060 | linknum == ScriptBaseClass.LINK_ALL_CHILDREN || | 7077 | linknum == ScriptBaseClass.LINK_ALL_CHILDREN || |
7061 | linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); | 7078 | linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); |
7062 | 7079 | ||
7063 | List<SceneObjectPart> parts = GetLinkParts(linknum); | 7080 | List<SceneObjectPart> parts = GetLinkParts(linknum); |
7064 | if (parts.Count == 0) return UUID.Zero.ToString(); | 7081 | if (parts.Count == 0) return UUID.Zero.ToString(); |
7065 | return parts[0].SitTargetAvatar.ToString(); | 7082 | return parts[0].SitTargetAvatar.ToString(); |
7066 | } | 7083 | } |
7067 | 7084 | ||
@@ -7451,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7451 | hollow = 0.70f; | 7468 | hollow = 0.70f; |
7452 | } | 7469 | } |
7453 | } | 7470 | } |
7454 | // Otherwise, hollow is limited to 95%. | 7471 | // Otherwise, hollow is limited to 95%. |
7455 | else | 7472 | else |
7456 | { | 7473 | { |
7457 | if (hollow > 0.95f) | 7474 | if (hollow > 0.95f) |
@@ -8906,16 +8923,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8906 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); | 8923 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); |
8907 | 8924 | ||
8908 | // float revolutions | 8925 | // float revolutions |
8909 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); | 8926 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); |
8910 | // Slightly inaccurate, because an unsigned byte is being used to represent | 8927 | // Slightly inaccurate, because an unsigned byte is being used to represent |
8911 | // the entire range of floating-point values from 1.0 through 4.0 (which is how | 8928 | // the entire range of floating-point values from 1.0 through 4.0 (which is how |
8912 | // SL does it). | 8929 | // SL does it). |
8913 | // | 8930 | // |
8914 | // Using these formulas to store and retrieve PathRevolutions, it is not | 8931 | // Using these formulas to store and retrieve PathRevolutions, it is not |
8915 | // possible to use all values between 1.00 and 4.00. For instance, you can't | 8932 | // possible to use all values between 1.00 and 4.00. For instance, you can't |
8916 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you | 8933 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you |
8917 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them | 8934 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them |
8918 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar | 8935 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar |
8919 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. | 8936 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. |
8920 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value | 8937 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value |
8921 | // such as 1.10. So, SL must store and retreive the actual user input rather | 8938 | // such as 1.10. So, SL must store and retreive the actual user input rather |
@@ -9199,7 +9216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9199 | case (int)ScriptBaseClass.PRIM_DESC: | 9216 | case (int)ScriptBaseClass.PRIM_DESC: |
9200 | res.Add(new LSL_String(part.Description)); | 9217 | res.Add(new LSL_String(part.Description)); |
9201 | break; | 9218 | break; |
9202 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | 9219 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: |
9203 | res.Add(new LSL_Rotation(part.RotationOffset)); | 9220 | res.Add(new LSL_Rotation(part.RotationOffset)); |
9204 | break; | 9221 | break; |
9205 | 9222 | ||
@@ -11127,9 +11144,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11127 | IHttpRequestModule httpScriptMod = | 11144 | IHttpRequestModule httpScriptMod = |
11128 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); | 11145 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); |
11129 | List<string> param = new List<string>(); | 11146 | List<string> param = new List<string>(); |
11130 | foreach (object o in parameters.Data) | 11147 | bool ok; |
11148 | Int32 flag; | ||
11149 | |||
11150 | for (int i = 0; i < parameters.Data.Length; i += 2) | ||
11131 | { | 11151 | { |
11132 | param.Add(o.ToString()); | 11152 | ok = Int32.TryParse(parameters.Data[i].ToString(), out flag); |
11153 | if (!ok || flag < 0 || | ||
11154 | flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE) | ||
11155 | { | ||
11156 | throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag"); | ||
11157 | } | ||
11158 | |||
11159 | param.Add(parameters.Data[i].ToString()); //Add parameter flag | ||
11160 | |||
11161 | if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER) | ||
11162 | { | ||
11163 | param.Add(parameters.Data[i+1].ToString()); //Add parameter value | ||
11164 | } | ||
11165 | else | ||
11166 | { | ||
11167 | //Parameters are in pairs and custom header takes | ||
11168 | //arguments in pairs so adjust for header marker. | ||
11169 | ++i; | ||
11170 | |||
11171 | //Maximum of 8 headers are allowed based on the | ||
11172 | //Second Life documentation for llHTTPRequest. | ||
11173 | for (int count = 1; count <= 8; ++count) | ||
11174 | { | ||
11175 | //Enough parameters remaining for (another) header? | ||
11176 | if (parameters.Data.Length - i < 2) | ||
11177 | { | ||
11178 | //There must be at least one name/value pair for custom header | ||
11179 | if (count == 1) | ||
11180 | throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString()); | ||
11181 | break; | ||
11182 | } | ||
11183 | |||
11184 | if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase)) | ||
11185 | throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString()); | ||
11186 | |||
11187 | param.Add(parameters.Data[i].ToString()); | ||
11188 | param.Add(parameters.Data[i+1].ToString()); | ||
11189 | |||
11190 | //Have we reached the end of the list of headers? | ||
11191 | //End is marked by a string with a single digit. | ||
11192 | if (i+2 >= parameters.Data.Length || | ||
11193 | Char.IsDigit(parameters.Data[i].ToString()[0])) | ||
11194 | { | ||
11195 | break; | ||
11196 | } | ||
11197 | |||
11198 | i += 2; | ||
11199 | } | ||
11200 | } | ||
11133 | } | 11201 | } |
11134 | 11202 | ||
11135 | Vector3 position = m_host.AbsolutePosition; | 11203 | Vector3 position = m_host.AbsolutePosition; |
@@ -11295,12 +11363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11295 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) | 11363 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) |
11296 | { | 11364 | { |
11297 | m_host.AddScriptLPS(1); | 11365 | m_host.AddScriptLPS(1); |
11298 | 11366 | ||
11299 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); | 11367 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); |
11300 | 11368 | ||
11301 | if (lo == null) | 11369 | if (lo == null) |
11302 | return 0; | 11370 | return 0; |
11303 | 11371 | ||
11304 | IPrimCounts pc = lo.PrimCounts; | 11372 | IPrimCounts pc = lo.PrimCounts; |
11305 | 11373 | ||
11306 | if (sim_wide != ScriptBaseClass.FALSE) | 11374 | if (sim_wide != ScriptBaseClass.FALSE) |
@@ -11330,7 +11398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11330 | else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) | 11398 | else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) |
11331 | return 0; // counts not implemented yet | 11399 | return 0; // counts not implemented yet |
11332 | } | 11400 | } |
11333 | 11401 | ||
11334 | return 0; | 11402 | return 0; |
11335 | } | 11403 | } |
11336 | 11404 | ||
@@ -11691,7 +11759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11691 | return ret; | 11759 | return ret; |
11692 | } | 11760 | } |
11693 | } | 11761 | } |
11694 | 11762 | ||
11695 | return new LSL_List(); | 11763 | return new LSL_List(); |
11696 | } | 11764 | } |
11697 | 11765 | ||
@@ -12071,7 +12139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12071 | // Vector3 bc = group.AbsolutePosition - rayEnd; | 12139 | // Vector3 bc = group.AbsolutePosition - rayEnd; |
12072 | 12140 | ||
12073 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); | 12141 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); |
12074 | 12142 | ||
12075 | // Too far off ray, don't bother | 12143 | // Too far off ray, don't bother |
12076 | if (d > radius) | 12144 | if (d > radius) |
12077 | return; | 12145 | return; |
@@ -12434,7 +12502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12434 | else | 12502 | else |
12435 | { | 12503 | { |
12436 | ScenePresence sp = World.GetScenePresence(result.ConsumerID); | 12504 | ScenePresence sp = World.GetScenePresence(result.ConsumerID); |
12437 | /// It it a boy? a girl? | 12505 | /// It it a boy? a girl? |
12438 | if (sp != null) | 12506 | if (sp != null) |
12439 | itemID = sp.UUID; | 12507 | itemID = sp.UUID; |
12440 | } | 12508 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index da3b31f..2f8154d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -356,6 +356,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
356 | public const int HTTP_MIMETYPE = 1; | 356 | public const int HTTP_MIMETYPE = 1; |
357 | public const int HTTP_BODY_MAXLENGTH = 2; | 357 | public const int HTTP_BODY_MAXLENGTH = 2; |
358 | public const int HTTP_VERIFY_CERT = 3; | 358 | public const int HTTP_VERIFY_CERT = 3; |
359 | public const int HTTP_VERBOSE_THROTTLE = 4; | ||
360 | public const int HTTP_CUSTOM_HEADER = 5; | ||
361 | public const int HTTP_PRAGMA_NO_CACHE = 6; | ||
359 | 362 | ||
360 | public const int PRIM_MATERIAL = 2; | 363 | public const int PRIM_MATERIAL = 2; |
361 | public const int PRIM_PHYSICS = 3; | 364 | public const int PRIM_PHYSICS = 3; |
@@ -636,7 +639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
636 | public const int TOUCH_INVALID_FACE = -1; | 639 | public const int TOUCH_INVALID_FACE = -1; |
637 | public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); | 640 | public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); |
638 | public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; | 641 | public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; |
639 | 642 | ||
640 | // constants for llGetPrimMediaParams/llSetPrimMediaParams | 643 | // constants for llGetPrimMediaParams/llSetPrimMediaParams |
641 | public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; | 644 | public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; |
642 | public const int PRIM_MEDIA_CONTROLS = 1; | 645 | public const int PRIM_MEDIA_CONTROLS = 1; |
@@ -653,10 +656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
653 | public const int PRIM_MEDIA_WHITELIST = 12; | 656 | public const int PRIM_MEDIA_WHITELIST = 12; |
654 | public const int PRIM_MEDIA_PERMS_INTERACT = 13; | 657 | public const int PRIM_MEDIA_PERMS_INTERACT = 13; |
655 | public const int PRIM_MEDIA_PERMS_CONTROL = 14; | 658 | public const int PRIM_MEDIA_PERMS_CONTROL = 14; |
656 | 659 | ||
657 | public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; | 660 | public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; |
658 | public const int PRIM_MEDIA_CONTROLS_MINI = 1; | 661 | public const int PRIM_MEDIA_CONTROLS_MINI = 1; |
659 | 662 | ||
660 | public const int PRIM_MEDIA_PERM_NONE = 0; | 663 | public const int PRIM_MEDIA_PERM_NONE = 0; |
661 | public const int PRIM_MEDIA_PERM_OWNER = 1; | 664 | public const int PRIM_MEDIA_PERM_OWNER = 1; |
662 | public const int PRIM_MEDIA_PERM_GROUP = 2; | 665 | public const int PRIM_MEDIA_PERM_GROUP = 2; |
@@ -689,7 +692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
689 | public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; | 692 | public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; |
690 | public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; | 693 | public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; |
691 | public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; | 694 | public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; |
692 | 695 | ||
693 | // Constants for osGetRegionStats | 696 | // Constants for osGetRegionStats |
694 | public const int STATS_TIME_DILATION = 0; | 697 | public const int STATS_TIME_DILATION = 0; |
695 | public const int STATS_SIM_FPS = 1; | 698 | public const int STATS_SIM_FPS = 1; |
@@ -742,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
742 | public static readonly LSLInteger RC_GET_ROOT_KEY = 2; | 745 | public static readonly LSLInteger RC_GET_ROOT_KEY = 2; |
743 | public static readonly LSLInteger RC_GET_LINK_NUM = 4; | 746 | public static readonly LSLInteger RC_GET_LINK_NUM = 4; |
744 | 747 | ||
745 | public static readonly LSLInteger RCERR_UNKNOWN = -1; | 748 | public static readonly LSLInteger RCERR_UNKNOWN = -1; |
746 | public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; | 749 | public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; |
747 | public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3; | 750 | public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3; |
748 | 751 | ||