diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 30e2b1bcd4..1e36853d0c 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -266,13 +266,19 @@ namespace OpenSim SavePrimsXml2); m_console.Commands.AddCommand("Archiving", false, "load oar", - "load oar [--merge] [--skip-assets] [--noterrain] [--displacement \"\"] []", + "load oar [--merge] [--skip-assets]" + + " [--forceterrain] [--forceparcels]" + + " [--rotation degrees] [--rotationCenter \"\"]" + + " [--displacement \"\"]" + + " []", "Load a region's data from an OAR archive.", - "--merge will merge the OAR with the existing scene." + Environment.NewLine + "--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading)." + Environment.NewLine + "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine + "--displacement will add this value to the position of every object loaded" + Environment.NewLine - + "--noterrain suppresses the loading of terrain from the oar" + Environment.NewLine - + "--noparcels suppresses the loading of parcels from the oar" + Environment.NewLine + + "--forceterrain forces the loading of terrain from the oar (undoes suppression done by --merge)" + Environment.NewLine + + "--forceparcels forces the loading of parcels from the oar (undoes suppression done by --merge)" + Environment.NewLine + + "--rotation specified rotation to be applied to the oar. Specified in degrees." + Environment.NewLine + + "--rotationcenter Location (relative to original OAR) to apply rotation. Default is <128,128,0>" + Environment.NewLine + "The path can be either a filesystem location or a URI." + " If this is not given then the command looks for an OAR named region.oar in the current directory.", LoadOar); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 637c4a3ad0..f4807addbb 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -96,18 +96,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Should the archive being loaded be merged with what is already on the region? + /// Merging usually suppresses terrain and parcel loading /// protected bool m_merge; /// - /// If true, suppresses the loading of terrain from the oar file + /// If true, force the loading of terrain from the oar file /// - protected bool m_noTerrain; + protected bool m_forceTerrain; /// - /// If true, suppresses the loading of parcels from the oar file + /// If true, force the loading of parcels from the oar file /// - protected bool m_noParcels; + protected bool m_forceParcels; /// /// Should we ignore any assets when reloading the archive? @@ -119,6 +120,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// protected Vector3 m_displacement = Vector3.Zero; + /// + /// Rotation to apply to the objects as they are loaded. + /// + protected float m_rotation = 0f; + + /// + /// Center around which to apply the rotation relative to the origional oar position + /// + protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); + /// /// Used to cache lookups for valid uuids. /// @@ -166,11 +177,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_errorMessage = String.Empty; m_merge = options.ContainsKey("merge"); - m_noTerrain = options.ContainsKey("noTerrain"); - m_noParcels = options.ContainsKey("noParcels"); + m_forceTerrain = options.ContainsKey("forceTerrain"); + m_forceParcels = options.ContainsKey("forceParcels"); m_skipAssets = options.ContainsKey("skipAssets"); m_requestId = requestId; m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero; + m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f; + m_rotationCenter = options.ContainsKey("rotationCenter") ? (Vector3)options["rotationCenter"] + : new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); // Zero can never be a valid user id m_validUserUuids[UUID.Zero] = false; @@ -261,7 +275,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver if ((successfulAssetRestores + failedAssetRestores) % 250 == 0) m_log.Debug("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets..."); } - else if (!m_noTerrain && !m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) + else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH) && (!m_merge || m_forceTerrain)) { LoadTerrain(scene, filePath, data); } @@ -269,7 +283,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver { LoadRegionSettings(scene, filePath, data, dearchivedScenes); } - else if (!m_noParcels && !m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) + else if (filePath.StartsWith(ArchiveConstants.LANDDATA_PATH) && (!m_merge || m_forceParcels)) { sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data)); } @@ -440,6 +454,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); + float angle = (float)(m_rotation / 180.0 * Math.PI); + OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, angle); + UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; IRegionSerialiserModule serialiser = scene.RequestModuleInterface(); @@ -464,7 +481,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); // Happily this does not do much to the object since it hasn't been added to the scene yet - sceneObject.AbsolutePosition += m_displacement; + if (sceneObject.AttachmentPoint == 0) + { + if (angle != 0f) + { + sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; + Vector3 offset = sceneObject.AbsolutePosition - m_rotationCenter; + offset *= rot; + sceneObject.AbsolutePosition = m_rotationCenter + offset; + } + if (m_displacement != Vector3.Zero) + { + sceneObject.AbsolutePosition += m_displacement; + } + } bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); @@ -571,6 +601,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver foreach (string serialisedParcel in serialisedParcels) { LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); + + if (m_displacement != Vector3.Zero) + { + Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f); + parcel.AABBMin += parcelDisp; + parcel.AABBMax += parcelDisp; + } // Validate User and Group UUID's diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index df5b4436c6..2a6f1eb23b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -104,19 +104,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver { bool mergeOar = false; bool skipAssets = false; - bool noTerrain = false; - bool noParcels = false; + bool forceTerrain = false; + bool forceParcels = false; Vector3 displacement = new Vector3(0f, 0f, 0f); + float rotation = 0f; + Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0); OptionSet options = new OptionSet(); options.Add("m|merge", delegate (string v) { mergeOar = (v != null); }); options.Add("s|skip-assets", delegate (string v) { skipAssets = (v != null); }); - options.Add("noterrain", delegate (string v) { noTerrain = (v != null); }); - options.Add("noparcels", delegate (string v) { noParcels = (v != null); }); + options.Add("forceterrain", delegate (string v) { forceTerrain = (v != null); }); + options.Add("forceparcels", delegate (string v) { forceParcels = (v != null); }); options.Add("displacement=", delegate (string v) { try { - displacement = v == null ? new Vector3(0f, 0f, 0f) : Vector3.Parse(v); + displacement = v == null ? Vector3.Zero : Vector3.Parse(v); } catch (Exception e) { @@ -124,6 +126,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver displacement = new Vector3(0f, 0f, 0f); } }); + options.Add("rotation=", delegate (string v) { + rotation = float.Parse(v); + rotation = Util.Clamp(rotation, -359f, 359f); + }); + options.Add("rotationcenter=", delegate (string v) { + // RA 20130119: libomv's Vector2.Parse doesn't work. Need to use vector3 for the moment + rotationCenter = Vector3.Parse(v); + }); // Send a message to the region ready module /* bluewall* Disable this for the time being @@ -145,9 +155,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver Dictionary archiveOptions = new Dictionary(); if (mergeOar) archiveOptions.Add("merge", null); if (skipAssets) archiveOptions.Add("skipAssets", null); - if (noTerrain) archiveOptions.Add("noTerrain", null); - if (noParcels) archiveOptions.Add("noParcels", null); - if (displacement != Vector3.Zero) archiveOptions.Add("displacement", displacement); + if (forceTerrain) archiveOptions.Add("forceTerrain", null); + if (forceParcels) archiveOptions.Add("forceParcels", null); + archiveOptions.Add("displacement", displacement); + archiveOptions.Add("rotation", rotation); + archiveOptions.Add("rotationCenter", rotationCenter); if (mainParams.Count > 2) {