diff options
Diffstat (limited to 'OpenSim')
4 files changed, 280 insertions, 56 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index a2ba8c0..4ab48e3 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -267,26 +267,36 @@ namespace OpenSim | |||
267 | SavePrimsXml2); | 267 | SavePrimsXml2); |
268 | 268 | ||
269 | m_console.Commands.AddCommand("Archiving", false, "load oar", | 269 | m_console.Commands.AddCommand("Archiving", false, "load oar", |
270 | "load oar [--merge] [--skip-assets]" | 270 | "load oar [-m|--merge] [-s|--skip-assets]" |
271 | + " [--default-user \"User Name\"]" | 271 | + " [--default-user \"User Name\"]" |
272 | + " [--force-terrain] [--force-parcels]" | 272 | + " [--force-terrain] [--force-parcels]" |
273 | + " [--no-objects]" | 273 | + " [--no-objects]" |
274 | + " [--rotation degrees] [--rotation-center \"<x,y,z>\"]" | 274 | + " [--rotation degrees]" |
275 | + " [--bounding-origin \"<x,y,z>\"]" | ||
276 | + " [--bounding-size \"<x,y,z>\"]" | ||
275 | + " [--displacement \"<x,y,z>\"]" | 277 | + " [--displacement \"<x,y,z>\"]" |
278 | + " [-d|--debug]" | ||
276 | + " [<OAR path>]", | 279 | + " [<OAR path>]", |
277 | "Load a region's data from an OAR archive.", | 280 | "Load a region's data from an OAR archive.", |
278 | "--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n" | 281 | "--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n" |
282 | + "--skip-assets will load the OAR but ignore the assets it contains.\n" | ||
279 | + "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n" | 283 | + "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n" |
280 | + "--displacement will add this value to the position of every object loaded.\n" | ||
281 | + "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n" | 284 | + "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n" |
282 | + "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n" | 285 | + "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n" |
283 | + "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n" | 286 | + "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n" |
284 | + "--rotation specified rotation to be applied to the oar. Specified in degrees.\n" | 287 | + "--rotation specified rotation to be applied to the oar. Specified in degrees.\n" |
285 | + "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>.\n" | 288 | + "--bounding-origin will only place objects that after displacement and rotation fall within the bounding cube who's position starts at <x,y,z>. Defaults to <0,0,0>.\n" |
286 | + "--skip-assets will load the OAR but ignore the assets it contains.\n\n" | 289 | + "--bounding-size specifies the size of the bounding cube. The default is the size of the destination region and cannot be larger than this.\n" |
290 | + "--displacement will add this value to the position of every object loaded.\n" | ||
291 | + "--debug forces the archiver to display messages about where each object is being placed.\n\n" | ||
287 | + "The path can be either a filesystem location or a URI.\n" | 292 | + "The path can be either a filesystem location or a URI.\n" |
288 | + " If this is not given then the command looks for an OAR named region.oar in the current directory.", | 293 | + " If this is not given then the command looks for an OAR named region.oar in the current directory." |
289 | LoadOar); | 294 | + " [--rotation-center \"<x,y,z>\"] used to be an option, now it does nothing and will be removed soon." |
295 | + "When an OAR is being loaded, operations are applied in this order:\n" | ||
296 | + "1: Rotation (around the incoming OARs region center)\n" | ||
297 | + "2: Cropping (a bounding cube with origin and size)\n" | ||
298 | + "3: Displacement (setting offset coordinates within the destination region)", | ||
299 | LoadOar); ; | ||
290 | 300 | ||
291 | m_console.Commands.AddCommand("Archiving", false, "save oar", | 301 | m_console.Commands.AddCommand("Archiving", false, "save oar", |
292 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", | 302 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", |
@@ -312,7 +322,7 @@ namespace OpenSim | |||
312 | 322 | ||
313 | m_console.Commands.AddCommand("Objects", false, "rotate scene", | 323 | m_console.Commands.AddCommand("Objects", false, "rotate scene", |
314 | "rotate scene <degrees> [centerX, centerY]", | 324 | "rotate scene <degrees> [centerX, centerY]", |
315 | "Rotates all scene objects around centerX, centerY (defailt 128, 128) (please back up your region before using)", | 325 | "Rotates all scene objects around centerX, centerY (default 128, 128) (please back up your region before using)", |
316 | HandleRotateScene); | 326 | HandleRotateScene); |
317 | 327 | ||
318 | m_console.Commands.AddCommand("Objects", false, "scale scene", | 328 | m_console.Commands.AddCommand("Objects", false, "scale scene", |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 40589de..623671f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring; | |||
40 | using OpenSim.Framework.Serialization; | 40 | using OpenSim.Framework.Serialization; |
41 | using OpenSim.Framework.Serialization.External; | 41 | using OpenSim.Framework.Serialization.External; |
42 | using OpenSim.Region.CoreModules.World.Terrain; | 42 | using OpenSim.Region.CoreModules.World.Terrain; |
43 | using OpenSim.Region.CoreModules.World.Land; | ||
43 | using OpenSim.Region.Framework.Interfaces; | 44 | using OpenSim.Region.Framework.Interfaces; |
44 | using OpenSim.Region.Framework.Scenes; | 45 | using OpenSim.Region.Framework.Scenes; |
45 | using OpenSim.Region.Framework.Scenes.Serialization; | 46 | using OpenSim.Region.Framework.Scenes.Serialization; |
@@ -131,7 +132,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
131 | /// </value> | 132 | /// </value> |
132 | protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); | 133 | protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); |
133 | 134 | ||
135 | /// <value> | ||
136 | /// Corner 1 of a bounding cuboid which specifies which objects we load from the oar | ||
137 | /// </value> | ||
138 | protected Vector3 m_boundingOrigin = Vector3.Zero; | ||
139 | |||
140 | /// <value> | ||
141 | /// Size of a bounding cuboid which specifies which objects we load from the oar | ||
142 | /// </value> | ||
143 | protected Vector3 m_boundingSize = new Vector3(Constants.MaximumRegionSize, Constants.MaximumRegionSize, Constants.MaximumRegionSize); | ||
144 | |||
134 | protected bool m_noObjects = false; | 145 | protected bool m_noObjects = false; |
146 | protected bool m_boundingBox = false; | ||
147 | protected bool m_debug = false; | ||
148 | |||
149 | protected Vector3 m_incomingRegionSize = new Vector3(256f, 256f, 4096f); | ||
135 | 150 | ||
136 | /// <summary> | 151 | /// <summary> |
137 | /// Used to cache lookups for valid uuids. | 152 | /// Used to cache lookups for valid uuids. |
@@ -202,6 +217,55 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
202 | m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"] | 217 | m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"] |
203 | : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f); | 218 | : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f); |
204 | 219 | ||
220 | m_boundingOrigin = Vector3.Zero; | ||
221 | m_boundingSize = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, Constants.RegionHeight); | ||
222 | |||
223 | if (options.ContainsKey("bounding-origin")) | ||
224 | { | ||
225 | Vector3 boOption = (Vector3)options["bounding-origin"]; | ||
226 | if (boOption.X >= 0 && boOption.X < m_boundingSize.X | ||
227 | && boOption.Y >= 0 && boOption.Y < m_boundingSize.Y | ||
228 | && boOption.Z >= 0 && boOption.Z < m_boundingSize.Z) | ||
229 | { | ||
230 | if (m_boundingOrigin != boOption) | ||
231 | { | ||
232 | m_boundingOrigin = boOption; | ||
233 | m_boundingBox = true; | ||
234 | } | ||
235 | } | ||
236 | else m_log.InfoFormat("[ARCHIVER]: The bounding cube origin must be within the destination region! Setting to {0}.", m_boundingOrigin.ToString()); | ||
237 | } | ||
238 | |||
239 | |||
240 | if (options.ContainsKey("bounding-size")) | ||
241 | { | ||
242 | Vector3 bsOption = (Vector3)options["bounding-size"]; | ||
243 | bool clip = false; | ||
244 | if (bsOption.X <= 0 && bsOption.X > (m_boundingSize.X - m_boundingOrigin.X)) | ||
245 | { | ||
246 | bsOption.X = m_boundingSize.X - m_boundingOrigin.X; | ||
247 | clip = true; | ||
248 | } | ||
249 | if (bsOption.Y <= 0 && bsOption.Y > (m_boundingSize.Y - m_boundingOrigin.Y)) | ||
250 | { | ||
251 | bsOption.Y = m_boundingSize.Y - m_boundingOrigin.Y; | ||
252 | clip = true; | ||
253 | } | ||
254 | if (bsOption.Z <= 0 && bsOption.Z > (m_boundingSize.Z - m_boundingOrigin.Z)) | ||
255 | { | ||
256 | bsOption.Z = m_boundingSize.Y - m_boundingOrigin.Z; | ||
257 | clip = true; | ||
258 | } | ||
259 | if (m_boundingSize != bsOption) | ||
260 | { | ||
261 | m_boundingSize = bsOption; | ||
262 | m_boundingBox = true; | ||
263 | if (clip) m_log.InfoFormat("[ARCHIVER]: The bounding cube specified is larger than the destination region! Clipping to {0}.", m_boundingSize.ToString()); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | m_debug = options.ContainsKey("debug"); | ||
268 | |||
205 | // Zero can never be a valid user id (or group) | 269 | // Zero can never be a valid user id (or group) |
206 | m_validUserUuids[UUID.Zero] = false; | 270 | m_validUserUuids[UUID.Zero] = false; |
207 | m_validGroupUuids[UUID.Zero] = false; | 271 | m_validGroupUuids[UUID.Zero] = false; |
@@ -435,7 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
435 | // If the control file wasn't the first file then reset the read pointer | 499 | // If the control file wasn't the first file then reset the read pointer |
436 | if (!firstFile) | 500 | if (!firstFile) |
437 | { | 501 | { |
438 | m_log.Warn("Control file wasn't the first file in the archive"); | 502 | m_log.Warn("[ARCHIVER]: Control file wasn't the first file in the archive"); |
439 | if (m_loadStream.CanSeek) | 503 | if (m_loadStream.CanSeek) |
440 | { | 504 | { |
441 | m_loadStream.Seek(0, SeekOrigin.Begin); | 505 | m_loadStream.Seek(0, SeekOrigin.Begin); |
@@ -452,7 +516,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
452 | else | 516 | else |
453 | { | 517 | { |
454 | // There isn't currently a scenario where this happens, but it's best to add a check just in case | 518 | // There isn't currently a scenario where this happens, but it's best to add a check just in case |
455 | throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking"); | 519 | throw new Exception("[ARCHIVER]: Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking"); |
456 | } | 520 | } |
457 | } | 521 | } |
458 | 522 | ||
@@ -462,7 +526,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
462 | firstFile = false; | 526 | firstFile = false; |
463 | } | 527 | } |
464 | 528 | ||
465 | throw new Exception("Control file not found"); | 529 | throw new Exception("[ARCHIVER]: Control file not found"); |
466 | } | 530 | } |
467 | 531 | ||
468 | /// <summary> | 532 | /// <summary> |
@@ -473,12 +537,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
473 | // Reload serialized prims | 537 | // Reload serialized prims |
474 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); | 538 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); |
475 | 539 | ||
476 | OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, m_rotation); | 540 | // Convert rotation to radians |
541 | double rotation = Math.PI * m_rotation / 180f; | ||
542 | |||
543 | OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, (float)rotation); | ||
477 | 544 | ||
478 | UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; | 545 | UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; |
479 | 546 | ||
480 | IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); | 547 | IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); |
481 | int sceneObjectsLoadedCount = 0; | 548 | int sceneObjectsLoadedCount = 0; |
549 | Vector3 boundingExtent = new Vector3(m_boundingOrigin.X + m_boundingSize.X, m_boundingOrigin.Y + m_boundingSize.Y, m_boundingOrigin.Z + m_boundingSize.Z); | ||
482 | 550 | ||
483 | foreach (string serialisedSceneObject in serialisedSceneObjects) | 551 | foreach (string serialisedSceneObject in serialisedSceneObjects) |
484 | { | 552 | { |
@@ -498,30 +566,50 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
498 | 566 | ||
499 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); | 567 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); |
500 | 568 | ||
569 | Vector3 pos = sceneObject.AbsolutePosition; | ||
570 | |||
571 | //fix the rotation center to the middle of the incoming region now as it's otherwise hopelessly confusing on varRegions | ||
572 | //as it only works with objects and terrain (using old Merge method) and not parcels | ||
573 | m_rotationCenter.X = m_incomingRegionSize.X / 2; | ||
574 | m_rotationCenter.Y = m_incomingRegionSize.Y / 2; | ||
575 | |||
576 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: Loading object from OAR with original scene position {0}.", pos.ToString()); | ||
501 | // Happily this does not do much to the object since it hasn't been added to the scene yet | 577 | // Happily this does not do much to the object since it hasn't been added to the scene yet |
502 | if (!sceneObject.IsAttachment) | 578 | if (!sceneObject.IsAttachment) |
503 | { | 579 | { |
504 | if (m_displacement != Vector3.Zero || m_rotation != 0f) | 580 | if (m_rotation != 0f) |
505 | { | 581 | { |
506 | Vector3 pos = sceneObject.AbsolutePosition; | 582 | // Rotate the object |
507 | if (m_rotation != 0f) | 583 | sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; |
508 | { | 584 | // Get object position relative to rotation axis |
509 | // Rotate the object | 585 | Vector3 offset = pos - m_rotationCenter; |
510 | sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; | 586 | // Rotate the object position |
511 | // Get object position relative to rotation axis | 587 | offset *= rot; |
512 | Vector3 offset = pos - m_rotationCenter; | 588 | // Restore the object position back to relative to the region |
513 | // Rotate the object position | 589 | pos = m_rotationCenter + offset; |
514 | offset *= rot; | 590 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: After rotation, object from OAR is at scene position {0}.", pos.ToString()); |
515 | // Restore the object position back to relative to the region | 591 | } |
516 | pos = m_rotationCenter + offset; | 592 | if (m_boundingBox) |
517 | } | 593 | { |
518 | if (m_displacement != Vector3.Zero) | 594 | if (pos.X < m_boundingOrigin.X || pos.X >= boundingExtent.X |
595 | || pos.Y < m_boundingOrigin.Y || pos.Y >= boundingExtent.Y | ||
596 | || pos.Z < m_boundingOrigin.Z || pos.Z >= boundingExtent.Z) | ||
519 | { | 597 | { |
520 | pos += m_displacement; | 598 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: Skipping object from OAR in scene because it's position {0} is outside of bounding cube.", pos.ToString()); |
599 | continue; | ||
521 | } | 600 | } |
522 | sceneObject.AbsolutePosition = pos; | 601 | //adjust object position to be relative to <0,0> so we can apply the displacement |
602 | pos.X -= m_boundingOrigin.X; | ||
603 | pos.Y -= m_boundingOrigin.Y; | ||
523 | } | 604 | } |
605 | if (m_displacement != Vector3.Zero) | ||
606 | { | ||
607 | pos += m_displacement; | ||
608 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: After displacement, object from OAR is at scene position {0}.", pos.ToString()); | ||
609 | } | ||
610 | sceneObject.AbsolutePosition = pos; | ||
524 | } | 611 | } |
612 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: Placing object from OAR in scene at position {0}. ", pos.ToString()); | ||
525 | 613 | ||
526 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); | 614 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); |
527 | 615 | ||
@@ -553,11 +641,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
553 | int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; | 641 | int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; |
554 | 642 | ||
555 | if (ignoredObjects > 0) | 643 | if (ignoredObjects > 0) |
556 | m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); | 644 | m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene or were out of bounds", ignoredObjects); |
557 | 645 | ||
558 | if (oldTelehubUUID != UUID.Zero) | 646 | if (oldTelehubUUID != UUID.Zero) |
559 | { | 647 | { |
560 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); | 648 | m_log.WarnFormat("[ARCHIVER]: Telehub object not found: {0}", oldTelehubUUID); |
561 | scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; | 649 | scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; |
562 | scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | 650 | scene.RegionInfo.RegionSettings.ClearSpawnPoints(); |
563 | } | 651 | } |
@@ -645,15 +733,86 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
645 | // Reload serialized parcels | 733 | // Reload serialized parcels |
646 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); | 734 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); |
647 | List<LandData> landData = new List<LandData>(); | 735 | List<LandData> landData = new List<LandData>(); |
736 | ILandObject landObject = scene.RequestModuleInterface<ILandObject>(); | ||
737 | List<ILandObject> parcels; | ||
738 | Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f); | ||
739 | Vector2 displacement = new Vector2(m_displacement.X, m_displacement.Y); | ||
740 | Vector2 boundingOrigin = new Vector2(m_boundingOrigin.X, m_boundingOrigin.Y); | ||
741 | Vector2 boundingSize = new Vector2(m_boundingSize.X, m_boundingSize.Y); | ||
742 | Vector2 regionSize = new Vector2(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY); | ||
743 | |||
744 | // Gather any existing parcels before we add any more. Later as we add parcels we can check if the new parcel | ||
745 | // data overlays any of the old data, and we can modify and remove (if empty) the old parcel so that there's no conflict | ||
746 | parcels = scene.LandChannel.AllParcels(); | ||
747 | |||
648 | foreach (string serialisedParcel in serialisedParcels) | 748 | foreach (string serialisedParcel in serialisedParcels) |
649 | { | 749 | { |
650 | LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); | 750 | LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); |
751 | bool overrideRegionSize = true; //use the src land parcel data size not the dst region size | ||
752 | bool isEmptyNow; | ||
753 | Vector3 AABBMin; | ||
754 | Vector3 AABBMax; | ||
755 | |||
756 | // create a new LandObject that we can use to manipulate the incoming source parcel data | ||
757 | // this is ok, but just beware that some of the LandObject functions (that we haven't used here) still | ||
758 | // assume we're always using the destination region size | ||
759 | LandData ld = new LandData(); | ||
760 | landObject = new LandObject(ld, scene); | ||
761 | landObject.LandData = parcel; | ||
762 | |||
763 | bool[,] srcLandBitmap = landObject.ConvertBytesToLandBitmap(overrideRegionSize); | ||
764 | if (landObject.IsLandBitmapEmpty(srcLandBitmap)) | ||
765 | { | ||
766 | m_log.InfoFormat("[ARCHIVER]: Skipping source parcel {0} with GlobalID: {1} LocalID: {2} that has no claimed land.", | ||
767 | parcel.Name, parcel.GlobalID, parcel.LocalID); | ||
768 | continue; | ||
769 | } | ||
770 | //m_log.DebugFormat("[ARCHIVER]: Showing claimed land for source parcel: {0} with GlobalID: {1} LocalID: {2}.", | ||
771 | // parcel.Name, parcel.GlobalID, parcel.LocalID); | ||
772 | //landObject.DebugLandBitmap(srcLandBitmap); | ||
651 | 773 | ||
652 | if (m_displacement != Vector3.Zero) | 774 | bool[,] dstLandBitmap = landObject.RemapLandBitmap(srcLandBitmap, displacement, m_rotation, boundingOrigin, boundingSize, regionSize, out isEmptyNow, out AABBMin, out AABBMax); |
775 | if (isEmptyNow) | ||
653 | { | 776 | { |
654 | Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f); | 777 | m_log.WarnFormat("[ARCHIVER]: Not adding destination parcel {0} with GlobalID: {1} LocalID: {2} because, after applying rotation, bounding and displacement, it has no claimed land.", |
655 | parcel.AABBMin += parcelDisp; | 778 | parcel.Name, parcel.GlobalID, parcel.LocalID); |
656 | parcel.AABBMax += parcelDisp; | 779 | continue; |
780 | } | ||
781 | //m_log.DebugFormat("[ARCHIVER]: Showing claimed land for destination parcel: {0} with GlobalID: {1} LocalID: {2} after applying rotation, bounding and displacement.", | ||
782 | // parcel.Name, parcel.GlobalID, parcel.LocalID); | ||
783 | //landObject.DebugLandBitmap(dstLandBitmap); | ||
784 | |||
785 | landObject.LandBitmap = dstLandBitmap; | ||
786 | parcel.Bitmap = landObject.ConvertLandBitmapToBytes(); | ||
787 | parcel.AABBMin = AABBMin; | ||
788 | parcel.AABBMax = AABBMax; | ||
789 | |||
790 | if (m_merge) | ||
791 | { | ||
792 | // give the remapped parcel a new GlobalID, in case we're using the same OAR twice and a bounding cube, displacement and --merge | ||
793 | parcel.GlobalID = UUID.Random(); | ||
794 | |||
795 | //now check if the area of this new incoming parcel overlays an area in any existing parcels | ||
796 | //and if so modify or lose the existing parcels | ||
797 | for (int i = 0; i < parcels.Count; i++) | ||
798 | { | ||
799 | if (parcels[i] != null) | ||
800 | { | ||
801 | bool[,] modLandBitmap = parcels[i].ConvertBytesToLandBitmap(overrideRegionSize); | ||
802 | modLandBitmap = parcels[i].RemoveFromLandBitmap(modLandBitmap, dstLandBitmap, out isEmptyNow, out AABBMin, out AABBMax); | ||
803 | if (isEmptyNow) | ||
804 | { | ||
805 | parcels[i] = null; | ||
806 | } | ||
807 | else | ||
808 | { | ||
809 | parcels[i].LandBitmap = modLandBitmap; | ||
810 | parcels[i].LandData.Bitmap = parcels[i].ConvertLandBitmapToBytes(); | ||
811 | parcels[i].LandData.AABBMin = AABBMin; | ||
812 | parcels[i].LandData.AABBMax = AABBMax; | ||
813 | } | ||
814 | } | ||
815 | } | ||
657 | } | 816 | } |
658 | 817 | ||
659 | // Validate User and Group UUID's | 818 | // Validate User and Group UUID's |
@@ -670,18 +829,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
670 | } | 829 | } |
671 | else | 830 | else |
672 | { | 831 | { |
673 | parcel.OwnerID = m_defaultUser; | 832 | parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; |
674 | parcel.GroupID = UUID.Zero; | ||
675 | parcel.IsGroupOwned = false; | 833 | parcel.IsGroupOwned = false; |
676 | } | 834 | } |
677 | } | 835 | } |
678 | else | 836 | else |
679 | { | 837 | { |
680 | if (!ResolveUserUuid(scene, parcel.OwnerID)) | 838 | if (!ResolveUserUuid(scene, parcel.OwnerID)) |
681 | parcel.OwnerID = m_defaultUser; | 839 | parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; |
682 | |||
683 | if (!ResolveGroupUuid(parcel.GroupID)) | ||
684 | parcel.GroupID = UUID.Zero; | ||
685 | } | 840 | } |
686 | 841 | ||
687 | List<LandAccessEntry> accessList = new List<LandAccessEntry>(); | 842 | List<LandAccessEntry> accessList = new List<LandAccessEntry>(); |
@@ -693,19 +848,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
693 | } | 848 | } |
694 | parcel.ParcelAccessList = accessList; | 849 | parcel.ParcelAccessList = accessList; |
695 | 850 | ||
696 | // m_log.DebugFormat( | 851 | if (m_debug) m_log.DebugFormat("[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}", |
697 | // "[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}", | 852 | parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area); |
698 | // parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area); | 853 | |
699 | |||
700 | landData.Add(parcel); | 854 | landData.Add(parcel); |
701 | } | 855 | } |
702 | 856 | ||
703 | if (!m_merge) | 857 | if (m_merge) |
704 | { | 858 | { |
705 | bool setupDefaultParcel = (landData.Count == 0); | 859 | for (int i = 0; i < parcels.Count; i++) //if merging then we need to also add back in any existing parcels |
706 | scene.LandChannel.Clear(setupDefaultParcel); | 860 | { |
861 | if (parcels[i] != null) landData.Add(parcels[i].LandData); | ||
862 | } | ||
707 | } | 863 | } |
708 | 864 | ||
865 | m_log.InfoFormat("[ARCHIVER]: Clearing {0} parcels.", parcels.Count); | ||
866 | bool setupDefaultParcel = (landData.Count == 0); | ||
867 | scene.LandChannel.Clear(setupDefaultParcel); | ||
709 | scene.EventManager.TriggerIncomingLandDataFromStorage(landData); | 868 | scene.EventManager.TriggerIncomingLandDataFromStorage(landData); |
710 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); | 869 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); |
711 | } | 870 | } |
@@ -934,10 +1093,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
934 | ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); | 1093 | ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); |
935 | using (MemoryStream ms = new MemoryStream(data)) | 1094 | using (MemoryStream ms = new MemoryStream(data)) |
936 | { | 1095 | { |
937 | if (m_displacement != Vector3.Zero || m_rotation != 0f) | 1096 | if (m_displacement != Vector3.Zero || m_rotation != 0f || m_boundingBox) |
938 | { | 1097 | { |
939 | Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y); | 1098 | Vector2 boundingOrigin = new Vector2(m_boundingOrigin.X, m_boundingOrigin.Y); |
940 | terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, rotationCenter, ms); | 1099 | Vector2 boundingSize = new Vector2(m_boundingSize.X, m_boundingSize.Y); |
1100 | terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, boundingOrigin, boundingSize, ms); ; | ||
941 | } | 1101 | } |
942 | else | 1102 | else |
943 | { | 1103 | { |
@@ -1014,6 +1174,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
1014 | { | 1174 | { |
1015 | dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString()); | 1175 | dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString()); |
1016 | } | 1176 | } |
1177 | else if (xtr.Name.ToString() == "size_in_meters") | ||
1178 | { | ||
1179 | Vector3 value; | ||
1180 | string size = "<" + xtr.ReadElementContentAsString() + ",0>"; | ||
1181 | if (Vector3.TryParse(size, out value)) | ||
1182 | { | ||
1183 | m_incomingRegionSize = value; | ||
1184 | dearchivedScenes.SetRegionSize(m_incomingRegionSize); | ||
1185 | m_log.DebugFormat("[ARCHIVER]: Found region_size info {0}", m_incomingRegionSize.ToString()); | ||
1186 | } | ||
1187 | } | ||
1017 | } | 1188 | } |
1018 | } | 1189 | } |
1019 | 1190 | ||
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 4178a57..cdc605b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -110,8 +110,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
110 | Vector3 displacement = new Vector3(0f, 0f, 0f); | 110 | Vector3 displacement = new Vector3(0f, 0f, 0f); |
111 | String defaultUser = ""; | 111 | String defaultUser = ""; |
112 | float rotation = 0f; | 112 | float rotation = 0f; |
113 | Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0); | 113 | Vector3 rotationCenter = new Vector3(Scene.RegionInfo.RegionSizeX / 2f, Scene.RegionInfo.RegionSizeY / 2f, 0); |
114 | 114 | Vector3 boundingOrigin = new Vector3(0f, 0f, 0f); | |
115 | Vector3 boundingSize = new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, Constants.RegionHeight); | ||
116 | bool debug = false; | ||
115 | 117 | ||
116 | OptionSet options = new OptionSet(); | 118 | OptionSet options = new OptionSet(); |
117 | options.Add("m|merge", delegate(string v) { mergeOar = (v != null); }); | 119 | options.Add("m|merge", delegate(string v) { mergeOar = (v != null); }); |
@@ -147,13 +149,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
147 | m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45"); | 149 | m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45"); |
148 | return; | 150 | return; |
149 | } | 151 | } |
150 | // Convert to radians for internals | 152 | //pass this in as degrees now, convert to radians later during actual work phase |
151 | rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI; | 153 | rotation = Util.Clamp<float>(rotation, -359f, 359f); |
152 | }); | 154 | }); |
153 | options.Add("rotation-center=", delegate(string v) | 155 | options.Add("rotation-center=", delegate(string v) |
154 | { | 156 | { |
155 | try | 157 | try |
156 | { | 158 | { |
159 | m_log.Info("[ARCHIVER MODULE] Warning: --rotation-center no longer does anything and will be removed soon!"); | ||
157 | rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v); | 160 | rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v); |
158 | } | 161 | } |
159 | catch | 162 | catch |
@@ -163,6 +166,33 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
163 | return; | 166 | return; |
164 | } | 167 | } |
165 | }); | 168 | }); |
169 | options.Add("bounding-origin=", delegate(string v) | ||
170 | { | ||
171 | try | ||
172 | { | ||
173 | boundingOrigin = v == null ? Vector3.Zero : Vector3.Parse(v); | ||
174 | } | ||
175 | catch | ||
176 | { | ||
177 | m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing bounding cube origin"); | ||
178 | m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --bounding-origin \"<128,128,0>\""); | ||
179 | return; | ||
180 | } | ||
181 | }); | ||
182 | options.Add("bounding-size=", delegate(string v) | ||
183 | { | ||
184 | try | ||
185 | { | ||
186 | boundingSize = v == null ? new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, Constants.RegionHeight) : Vector3.Parse(v); | ||
187 | } | ||
188 | catch | ||
189 | { | ||
190 | m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing bounding cube size"); | ||
191 | m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as a positive vector3: --bounding-size \"<256,256,4096>\""); | ||
192 | return; | ||
193 | } | ||
194 | }); | ||
195 | options.Add("d|debug", delegate(string v) { debug = (v != null); }); | ||
166 | 196 | ||
167 | // Send a message to the region ready module | 197 | // Send a message to the region ready module |
168 | /* bluewall* Disable this for the time being | 198 | /* bluewall* Disable this for the time being |
@@ -211,6 +241,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
211 | archiveOptions.Add("displacement", displacement); | 241 | archiveOptions.Add("displacement", displacement); |
212 | archiveOptions.Add("rotation", rotation); | 242 | archiveOptions.Add("rotation", rotation); |
213 | archiveOptions.Add("rotation-center", rotationCenter); | 243 | archiveOptions.Add("rotation-center", rotationCenter); |
244 | archiveOptions.Add("bounding-origin", boundingOrigin); | ||
245 | archiveOptions.Add("bounding-size", boundingSize); | ||
246 | if (debug) archiveOptions.Add("debug", null); | ||
214 | 247 | ||
215 | if (mainParams.Count > 2) | 248 | if (mainParams.Count > 2) |
216 | { | 249 | { |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs index 3dcc020..12a520f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs | |||
@@ -70,6 +70,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
70 | /// If null then the region doesn't have a corresponding scene, and it won't be loaded. | 70 | /// If null then the region doesn't have a corresponding scene, and it won't be loaded. |
71 | /// </summary> | 71 | /// </summary> |
72 | public Scene Scene { get; set; } | 72 | public Scene Scene { get; set; } |
73 | |||
74 | /// <summary> | ||
75 | /// The size of the region being loaded. | ||
76 | /// </summary> | ||
77 | public Vector3 RegionSize { get; set; } | ||
73 | } | 78 | } |
74 | 79 | ||
75 | /// <summary> | 80 | /// <summary> |
@@ -118,7 +123,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
118 | 123 | ||
119 | public void SetRegionOriginalID(string id) | 124 | public void SetRegionOriginalID(string id) |
120 | { | 125 | { |
121 | m_curRegion = new RegionInfo(); | 126 | if (m_curRegion == null) m_curRegion = new RegionInfo(); |
122 | m_curRegion.Location = new Point((int)m_curX, (int)m_curY); | 127 | m_curRegion.Location = new Point((int)m_curX, (int)m_curY); |
123 | m_curRegion.OriginalID = id; | 128 | m_curRegion.OriginalID = id; |
124 | // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called | 129 | // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called |
@@ -130,6 +135,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
130 | m_directory2region[directory] = m_curRegion; | 135 | m_directory2region[directory] = m_curRegion; |
131 | } | 136 | } |
132 | 137 | ||
138 | public void SetRegionSize(Vector3 size) | ||
139 | { | ||
140 | if (m_curRegion == null) m_curRegion = new RegionInfo(); | ||
141 | m_curRegion.RegionSize = size; | ||
142 | } | ||
133 | 143 | ||
134 | /// <summary> | 144 | /// <summary> |
135 | /// Sets all the scenes present in the simulator. | 145 | /// Sets all the scenes present in the simulator. |