aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs459
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs9
3 files changed, 274 insertions, 198 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 8d0c35a..88dff02 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Xml;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33 34
@@ -205,11 +206,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
205 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, 206 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
206 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) 207 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
207 { 208 {
208 // HACK: This is only working for lists containing a single item!
209 // It's just a hack to make this WIP compile and run. Nothing
210 // currently calls this with multiple items.
211 UUID ret = UUID.Zero; 209 UUID ret = UUID.Zero;
212 210
211 // The following code groups the SOG's by owner. No objects
212 // belonging to different people can be coalesced, for obvious
213 // reasons.
213 Dictionary<UUID, List<SceneObjectGroup>> deletes = 214 Dictionary<UUID, List<SceneObjectGroup>> deletes =
214 new Dictionary<UUID, List<SceneObjectGroup>>(); 215 new Dictionary<UUID, List<SceneObjectGroup>>();
215 216
@@ -221,262 +222,328 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
221 deletes[g.OwnerID].Add(g); 222 deletes[g.OwnerID].Add(g);
222 } 223 }
223 224
225 // This is pethod scoped and will be returned. It will be the
226 // last created asset id
227 UUID assetID = UUID.Zero;
228
229 // Each iteration is really a separate asset being created,
230 // with distinct destinations as well.
224 foreach (List<SceneObjectGroup> objlist in deletes.Values) 231 foreach (List<SceneObjectGroup> objlist in deletes.Values)
225 { 232 {
226 foreach (SceneObjectGroup g in objlist) 233 Dictionary<UUID, string> xmlStrings =
227 ret = DeleteToInventory(action, folderID, g, remoteClient); 234 new Dictionary<UUID, string>();
228 }
229
230 return ret;
231 }
232 235
233 private UUID DeleteToInventory(DeRezAction action, UUID folderID, 236 foreach (SceneObjectGroup objectGroup in objlist)
234 SceneObjectGroup objectGroup, IClientAPI remoteClient) 237 {
235 { 238 Vector3 inventoryStoredPosition = new Vector3
236 UUID assetID = UUID.Zero; 239 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
240 ? 250
241 : objectGroup.AbsolutePosition.X)
242 ,
243 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
244 ? 250
245 : objectGroup.AbsolutePosition.X,
246 objectGroup.AbsolutePosition.Z);
237 247
238 Vector3 inventoryStoredPosition = new Vector3 248 Vector3 originalPosition = objectGroup.AbsolutePosition;
239 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
240 ? 250
241 : objectGroup.AbsolutePosition.X)
242 ,
243 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
244 ? 250
245 : objectGroup.AbsolutePosition.X,
246 objectGroup.AbsolutePosition.Z);
247 249
248 Vector3 originalPosition = objectGroup.AbsolutePosition; 250 // Restore attachment data after trip through the sim
251 if (objectGroup.RootPart.AttachPoint > 0)
252 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
253 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
249 254
250 objectGroup.AbsolutePosition = inventoryStoredPosition; 255 objectGroup.AbsolutePosition = inventoryStoredPosition;
251 256
252 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); 257 // Make sure all bits but the ones we want are clear
258 // on take.
259 // This will be applied to the current perms, so
260 // it will do what we want.
261 objectGroup.RootPart.NextOwnerMask &=
262 ((uint)PermissionMask.Copy |
263 (uint)PermissionMask.Transfer |
264 (uint)PermissionMask.Modify);
265 objectGroup.RootPart.NextOwnerMask |=
266 (uint)PermissionMask.Move;
253 267
254 objectGroup.AbsolutePosition = originalPosition; 268 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
255 269
256 // Get the user info of the item destination 270 objectGroup.AbsolutePosition = originalPosition;
257 //
258 UUID userID = UUID.Zero;
259 271
260 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || 272 xmlStrings[objectGroup.UUID] = sceneObjectXml;
261 action == DeRezAction.SaveToExistingUserInventoryItem) 273 }
262 {
263 // Take or take copy require a taker
264 // Saving changes requires a local user
265 //
266 if (remoteClient == null)
267 return UUID.Zero;
268 274
269 userID = remoteClient.AgentId; 275 string itemXml;
270 }
271 else
272 {
273 // All returns / deletes go to the object owner
274 //
275 276
276 userID = objectGroup.RootPart.OwnerID; 277 if (objlist.Count > 1)
277 } 278 {
279 float minX, minY, minZ;
280 float maxX, maxY, maxZ;
278 281
279 if (userID == UUID.Zero) // Can't proceed 282 Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist,
280 { 283 out minX, out maxX, out minY, out maxY,
281 return UUID.Zero; 284 out minZ, out maxZ);
282 }
283 285
284 // If we're returning someone's item, it goes back to the 286 // CreateWrapper
285 // owner's Lost And Found folder. 287 XmlDocument itemDoc = new XmlDocument();
286 // Delete is treated like return in this case 288 XmlElement root = itemDoc.CreateElement("", "CoalescedObject", "");
287 // Deleting your own items makes them go to trash 289 itemDoc.AppendChild(root);
288 //
289 290
290 InventoryFolderBase folder = null; 291 // Embed the offsets into the group XML
291 InventoryItemBase item = null; 292 for ( int i = 0 ; i < objlist.Count ; i++ )
293 {
294 XmlDocument doc = new XmlDocument();
295 SceneObjectGroup g = objlist[i];
296 doc.LoadXml(xmlStrings[g.UUID]);
297 XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup");
298 e.SetAttribute("offsetx", offsets[i].X.ToString());
299 e.SetAttribute("offsety", offsets[i].Y.ToString());
300 e.SetAttribute("offsetz", offsets[i].Z.ToString());
301
302 XmlNode objectNode = itemDoc.ImportNode(e, true);
303 root.AppendChild(objectNode);
304 }
292 305
293 if (DeRezAction.SaveToExistingUserInventoryItem == action) 306 float sizeX = maxX - minX;
294 { 307 float sizeY = maxY - minY;
295 item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); 308 float sizeZ = maxZ - minZ;
296 item = m_Scene.InventoryService.GetItem(item);
297 309
298 //item = userInfo.RootFolder.FindItem( 310 root.SetAttribute("x", sizeX.ToString());
299 // objectGroup.RootPart.FromUserInventoryItemID); 311 root.SetAttribute("y", sizeY.ToString());
312 root.SetAttribute("z", sizeZ.ToString());
300 313
301 if (null == item) 314 itemXml = itemDoc.InnerXml;
315 }
316 else
302 { 317 {
303 m_log.DebugFormat( 318 itemXml = xmlStrings[objlist[0].UUID];
304 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
305 objectGroup.Name, objectGroup.UUID);
306 return UUID.Zero;
307 } 319 }
308 } 320
309 else 321 // Get the user info of the item destination
310 {
311 // Folder magic
312 // 322 //
313 if (action == DeRezAction.Delete) 323 UUID userID = UUID.Zero;
324
325 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
326 action == DeRezAction.SaveToExistingUserInventoryItem)
314 { 327 {
315 // Deleting someone else's item 328 // Take or take copy require a taker
329 // Saving changes requires a local user
316 // 330 //
317 if (remoteClient == null || 331 if (remoteClient == null)
318 objectGroup.OwnerID != remoteClient.AgentId) 332 return UUID.Zero;
319 {
320 333
321 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 334 userID = remoteClient.AgentId;
322 }
323 else
324 {
325 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
326 }
327 } 335 }
328 else if (action == DeRezAction.Return) 336 else
329 { 337 {
330 338 // All returns / deletes go to the object owner
331 // Dump to lost + found unconditionally
332 // 339 //
333 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 340
341 userID = objlist[0].RootPart.OwnerID;
334 } 342 }
335 343
336 if (folderID == UUID.Zero && folder == null) 344 if (userID == UUID.Zero) // Can't proceed
337 { 345 {
338 if (action == DeRezAction.Delete) 346 return UUID.Zero;
347 }
348
349 // If we're returning someone's item, it goes back to the
350 // owner's Lost And Found folder.
351 // Delete is treated like return in this case
352 // Deleting your own items makes them go to trash
353 //
354
355 InventoryFolderBase folder = null;
356 InventoryItemBase item = null;
357
358 if (DeRezAction.SaveToExistingUserInventoryItem == action)
359 {
360 item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID);
361 item = m_Scene.InventoryService.GetItem(item);
362
363 //item = userInfo.RootFolder.FindItem(
364 // objectGroup.RootPart.FromUserInventoryItemID);
365
366 if (null == item)
339 { 367 {
340 // Deletes go to trash by default 368 m_log.DebugFormat(
341 // 369 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
342 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); 370 objlist[0].Name, objlist[0].UUID);
371 return UUID.Zero;
343 } 372 }
344 else 373 }
374 else
375 {
376 // Folder magic
377 //
378 if (action == DeRezAction.Delete)
345 { 379 {
380 // Deleting someone else's item
381 //
346 if (remoteClient == null || 382 if (remoteClient == null ||
347 objectGroup.OwnerID != remoteClient.AgentId) 383 objlist[0].OwnerID != remoteClient.AgentId)
348 { 384 {
349 // Taking copy of another person's item. Take to 385
350 // Objects folder. 386 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
351 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
352 } 387 }
353 else 388 else
354 { 389 {
355 // Catch all. Use lost & found 390 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
391 }
392 }
393 else if (action == DeRezAction.Return)
394 {
395
396 // Dump to lost + found unconditionally
397 //
398 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
399 }
400
401 if (folderID == UUID.Zero && folder == null)
402 {
403 if (action == DeRezAction.Delete)
404 {
405 // Deletes go to trash by default
356 // 406 //
407 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
408 }
409 else
410 {
411 if (remoteClient == null ||
412 objlist[0].OwnerID != remoteClient.AgentId)
413 {
414 // Taking copy of another person's item. Take to
415 // Objects folder.
416 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
417 }
418 else
419 {
420 // Catch all. Use lost & found
421 //
357 422
358 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 423 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
424 }
359 } 425 }
360 } 426 }
361 }
362 427
363 // Override and put into where it came from, if it came 428 // Override and put into where it came from, if it came
364 // from anywhere in inventory 429 // from anywhere in inventory
365 // 430 //
366 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) 431 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
367 {
368 if (objectGroup.RootPart.FromFolderID != UUID.Zero)
369 { 432 {
370 InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); 433 if (objlist[0].RootPart.FromFolderID != UUID.Zero)
371 folder = m_Scene.InventoryService.GetFolder(f); 434 {
435 InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID);
436 folder = m_Scene.InventoryService.GetFolder(f);
437 }
372 } 438 }
373 }
374
375 if (folder == null) // None of the above
376 {
377 folder = new InventoryFolderBase(folderID);
378 439
379 if (folder == null) // Nowhere to put it 440 if (folder == null) // None of the above
380 { 441 {
381 return UUID.Zero; 442 folder = new InventoryFolderBase(folderID);
382 }
383 }
384 443
385 item = new InventoryItemBase(); 444 if (folder == null) // Nowhere to put it
386 item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); 445 {
387 item.CreatorData = objectGroup.RootPart.CreatorData; 446 return UUID.Zero;
388 item.ID = UUID.Random(); 447 }
389 item.InvType = (int)InventoryType.Object; 448 }
390 item.Folder = folder.ID;
391 item.Owner = userID;
392 }
393 449
394 AssetBase asset = CreateAsset( 450 item = new InventoryItemBase();
395 objectGroup.GetPartName(objectGroup.RootPart.LocalId), 451 // Can't know creator is the same, so null it in inventory
396 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), 452 if (objlist.Count > 1)
397 (sbyte)AssetType.Object, 453 item.CreatorId = UUID.Zero.ToString();
398 Utils.StringToBytes(sceneObjectXml), 454 else
399 objectGroup.OwnerID.ToString()); 455 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
400 m_Scene.AssetService.Store(asset); 456 item.ID = UUID.Random();
401 assetID = asset.FullID; 457 item.InvType = (int)InventoryType.Object;
458 item.Folder = folder.ID;
459 item.Owner = userID;
460 if (objlist.Count > 1)
461 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
462 }
402 463
403 if (DeRezAction.SaveToExistingUserInventoryItem == action) 464 AssetBase asset = CreateAsset(
404 { 465 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
405 item.AssetID = asset.FullID; 466 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
406 m_Scene.InventoryService.UpdateItem(item); 467 (sbyte)AssetType.Object,
407 } 468 Utils.StringToBytes(itemXml),
408 else 469 objlist[0].OwnerID.ToString());
409 { 470 m_Scene.AssetService.Store(asset);
410 item.AssetID = asset.FullID; 471 assetID = asset.FullID;
411 472
412 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 473 if (DeRezAction.SaveToExistingUserInventoryItem == action)
413 { 474 {
414 uint perms = objectGroup.GetEffectivePermissions(); 475 item.AssetID = asset.FullID;
415 uint nextPerms = (perms & 7) << 13; 476 m_Scene.InventoryService.UpdateItem(item);
416 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
417 perms &= ~(uint)PermissionMask.Copy;
418 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
419 perms &= ~(uint)PermissionMask.Transfer;
420 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
421 perms &= ~(uint)PermissionMask.Modify;
422
423 // Make sure all bits but the ones we want are clear
424 // on take.
425 // This will be applied to the current perms, so
426 // it will do what we want.
427 objectGroup.RootPart.NextOwnerMask &=
428 ((uint)PermissionMask.Copy |
429 (uint)PermissionMask.Transfer |
430 (uint)PermissionMask.Modify);
431 objectGroup.RootPart.NextOwnerMask |=
432 (uint)PermissionMask.Move;
433
434 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
435 item.CurrentPermissions = item.BasePermissions;
436 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
437 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
438 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
439
440 item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
441 } 477 }
442 else 478 else
443 { 479 {
444 item.BasePermissions = objectGroup.GetEffectivePermissions(); 480 item.AssetID = asset.FullID;
445 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
446 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
447 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
448 item.GroupPermissions = objectGroup.RootPart.GroupMask;
449 481
450 item.CurrentPermissions &= 482 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
451 ((uint)PermissionMask.Copy | 483 foreach (SceneObjectGroup grp in objlist)
452 (uint)PermissionMask.Transfer | 484 effectivePerms &= grp.GetEffectivePermissions();
453 (uint)PermissionMask.Modify | 485 effectivePerms |= (uint)PermissionMask.Move;
454 (uint)PermissionMask.Move |
455 7); // Preserve folded permissions
456 }
457 486
458 // TODO: add the new fields (Flags, Sale info, etc) 487 if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
459 item.CreationDate = Util.UnixTimeSinceEpoch(); 488 {
460 item.Description = asset.Description; 489 uint perms = effectivePerms;
461 item.Name = asset.Name; 490 uint nextPerms = (perms & 7) << 13;
462 item.AssetType = asset.Type; 491 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
492 perms &= ~(uint)PermissionMask.Copy;
493 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
494 perms &= ~(uint)PermissionMask.Transfer;
495 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
496 perms &= ~(uint)PermissionMask.Modify;
497
498 item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask;
499 item.CurrentPermissions = item.BasePermissions;
500 item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask;
501 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask;
502 item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask;
503
504 // Magic number badness. Maybe this deserves an enum.
505 // bit 4 (16) is the "Slam" bit, it means treat as passed
506 // and apply next owner perms on rez
507 item.CurrentPermissions |= 16; // Slam!
508 }
509 else
510 {
511 item.BasePermissions = effectivePerms;
512 item.CurrentPermissions = effectivePerms;
513 item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms;
514 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms;
515 item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms;
516
517 item.CurrentPermissions &=
518 ((uint)PermissionMask.Copy |
519 (uint)PermissionMask.Transfer |
520 (uint)PermissionMask.Modify |
521 (uint)PermissionMask.Move |
522 7); // Preserve folded permissions
523 }
463 524
464 m_Scene.AddInventoryItem(item); 525 // TODO: add the new fields (Flags, Sale info, etc)
526 item.CreationDate = Util.UnixTimeSinceEpoch();
527 item.Description = asset.Description;
528 item.Name = asset.Name;
529 item.AssetType = asset.Type;
465 530
466 if (remoteClient != null && item.Owner == remoteClient.AgentId) 531 m_Scene.AddInventoryItem(item);
467 { 532
468 remoteClient.SendInventoryItemCreateUpdate(item, 0); 533 if (remoteClient != null && item.Owner == remoteClient.AgentId)
469 }
470 else
471 {
472 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
473 if (notifyUser != null)
474 { 534 {
475 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); 535 remoteClient.SendInventoryItemCreateUpdate(item, 0);
536 }
537 else
538 {
539 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
540 if (notifyUser != null)
541 {
542 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
543 }
476 } 544 }
477 } 545 }
478 } 546 }
479
480 return assetID; 547 return assetID;
481 } 548 }
482 549
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 64567db..8feb022 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
137 x = m_inventoryDeletes.Dequeue(); 137 x = m_inventoryDeletes.Dequeue();
138 138
139 m_log.DebugFormat( 139 m_log.DebugFormat(
140 "[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left); 140 "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count);
141 141
142 try 142 try
143 { 143 {
@@ -177,4 +177,4 @@ namespace OpenSim.Region.Framework.Scenes
177 return false; 177 return false;
178 } 178 }
179 } 179 }
180} \ No newline at end of file 180}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 353b7c2..35a798e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4865,8 +4865,17 @@ namespace OpenSim.Region.Framework.Scenes
4865 { 4865 {
4866 float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; 4866 float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
4867 4867
4868 Vector3 vec = g.AbsolutePosition;
4869
4868 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); 4870 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
4869 4871
4872 ominX += vec.X;
4873 omaxX += vec.X;
4874 ominY += vec.Y;
4875 omaxY += vec.Y;
4876 ominZ += vec.Z;
4877 omaxZ += vec.Z;
4878
4870 if (minX > ominX) 4879 if (minX > ominX)
4871 minX = ominX; 4880 minX = ominX;
4872 if (minY > ominY) 4881 if (minY > ominY)