aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs40
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs35
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs3
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITerrainModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs72
6 files changed, 129 insertions, 54 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index f4807ad..6f68966 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
121 protected Vector3 m_displacement = Vector3.Zero; 121 protected Vector3 m_displacement = Vector3.Zero;
122 122
123 /// <value> 123 /// <value>
124 /// Rotation to apply to the objects as they are loaded. 124 /// Rotation (in radians) to apply to the objects as they are loaded.
125 /// </value> 125 /// </value>
126 protected float m_rotation = 0f; 126 protected float m_rotation = 0f;
127 127
@@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
184 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero; 184 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero;
185 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f; 185 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f;
186 m_rotationCenter = options.ContainsKey("rotationCenter") ? (Vector3)options["rotationCenter"] 186 m_rotationCenter = options.ContainsKey("rotationCenter") ? (Vector3)options["rotationCenter"]
187 : new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); 187 : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f);
188 188
189 // Zero can never be a valid user id 189 // Zero can never be a valid user id
190 m_validUserUuids[UUID.Zero] = false; 190 m_validUserUuids[UUID.Zero] = false;
@@ -454,8 +454,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
454 // Reload serialized prims 454 // Reload serialized prims
455 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 455 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
456 456
457 float angle = (float)(m_rotation / 180.0 * Math.PI); 457 OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, m_rotation);
458 OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, angle);
459 458
460 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; 459 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject;
461 460
@@ -483,16 +482,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
483 // Happily this does not do much to the object since it hasn't been added to the scene yet 482 // Happily this does not do much to the object since it hasn't been added to the scene yet
484 if (sceneObject.AttachmentPoint == 0) 483 if (sceneObject.AttachmentPoint == 0)
485 { 484 {
486 if (angle != 0f) 485 if (m_displacement != Vector3.Zero || m_rotation != 0f)
487 { 486 {
488 sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; 487 Vector3 pos = sceneObject.AbsolutePosition;
489 Vector3 offset = sceneObject.AbsolutePosition - m_rotationCenter; 488 if (m_rotation != 0f)
490 offset *= rot; 489 {
491 sceneObject.AbsolutePosition = m_rotationCenter + offset; 490 // Rotate the object
492 } 491 sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation;
493 if (m_displacement != Vector3.Zero) 492 // Get object position relative to rotation axis
494 { 493 Vector3 offset = pos - m_rotationCenter;
495 sceneObject.AbsolutePosition += m_displacement; 494 // Rotate the object position
495 offset *= rot;
496 // Restore the object position back to relative to the region
497 pos = m_rotationCenter + offset;
498 }
499 if (m_displacement != Vector3.Zero)
500 {
501 pos += m_displacement;
502 }
503 sceneObject.AbsolutePosition = pos;
496 } 504 }
497 } 505 }
498 506
@@ -868,10 +876,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
868 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); 876 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
869 877
870 MemoryStream ms = new MemoryStream(data); 878 MemoryStream ms = new MemoryStream(data);
871 if (m_displacement != Vector3.Zero) 879 if (m_displacement != Vector3.Zero || m_rotation != 0f)
872 { 880 {
873 Vector2 terrainDisplacement = new Vector2(m_displacement.X, m_displacement.Y); 881 Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y);
874 terrainModule.LoadFromStream(terrainPath, terrainDisplacement, ms); 882 terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, rotationCenter, ms);
875 } 883 }
876 else 884 else
877 { 885 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 2a6f1eb..6fbac4c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -120,19 +120,38 @@ namespace OpenSim.Region.CoreModules.World.Archiver
120 { 120 {
121 displacement = v == null ? Vector3.Zero : Vector3.Parse(v); 121 displacement = v == null ? Vector3.Zero : Vector3.Parse(v);
122 } 122 }
123 catch (Exception e) 123 catch
124 { 124 {
125 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing displacement"); 125 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing displacement");
126 displacement = new Vector3(0f, 0f, 0f); 126 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --displacement \"<128,128,0>\"");
127 return;
127 } 128 }
128 }); 129 });
129 options.Add("rotation=", delegate (string v) { 130 options.Add("rotation=", delegate (string v) {
130 rotation = float.Parse(v); 131 try
131 rotation = Util.Clamp<float>(rotation, -359f, 359f); 132 {
133 rotation = v == null ? 0f : float.Parse(v);
134 }
135 catch
136 {
137 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation");
138 m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45");
139 return;
140 }
141 // Convert to radians for internals
142 rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI;
132 }); 143 });
133 options.Add("rotationcenter=", delegate (string v) { 144 options.Add("rotationcenter=", delegate (string v) {
134 // RA 20130119: libomv's Vector2.Parse doesn't work. Need to use vector3 for the moment 145 try
135 rotationCenter = Vector3.Parse(v); 146 {
147 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v);
148 }
149 catch
150 {
151 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation displacement");
152 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --rotationcenter \"<128,128,0>\"");
153 return;
154 }
136 }); 155 });
137 156
138 // Send a message to the region ready module 157 // Send a message to the region ready module
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 7bc5e88..08891d9 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -316,8 +316,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
316 316
317 public void LoadFromStream(string filename, Stream stream) 317 public void LoadFromStream(string filename, Stream stream)
318 { 318 {
319 Vector2 defaultDisplacement = new Vector2(0f, 0f); 319 LoadFromStream(filename, Vector3.Zero, 0f, Vector2.Zero, stream);
320 LoadFromStream(filename, defaultDisplacement, stream);
321 } 320 }
322 321
323 /// <summary> 322 /// <summary>
@@ -325,7 +324,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
325 /// </summary> 324 /// </summary>
326 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> 325 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
327 /// <param name="stream"></param> 326 /// <param name="stream"></param>
328 public void LoadFromStream(string filename, Vector2 displacement, Stream stream) 327 public void LoadFromStream(string filename, Vector3 displacement,
328 float radianRotation, Vector2 rotationDisplacement, Stream stream)
329 { 329 {
330 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 330 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
331 { 331 {
@@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
336 try 336 try
337 { 337 {
338 ITerrainChannel channel = loader.Value.LoadStream(stream); 338 ITerrainChannel channel = loader.Value.LoadStream(stream);
339 MergeTerrainIntoExisting(channel, displacement); 339 m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement);
340 UpdateRevertMap(); 340 UpdateRevertMap();
341 } 341 }
342 catch (NotImplementedException) 342 catch (NotImplementedException)
@@ -356,33 +356,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
356 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); 356 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
357 } 357 }
358 358
359 private void MergeTerrainIntoExisting(ITerrainChannel channel, Vector2 displacement)
360 {
361 if (displacement == Vector2.Zero)
362 {
363 // If there is no displacement, just use this channel as the new heightmap
364 m_scene.Heightmap = channel;
365 m_channel = channel;
366 }
367 else
368 {
369 // If there is a displacement, we copy the loaded heightmap into the overall region
370 for (int xx = 0; xx < channel.Width; xx++)
371 {
372 for (int yy = 0; yy < channel.Height; yy++)
373 {
374 int dispX = xx + (int)displacement.X;
375 int dispY = yy + (int)displacement.Y;
376 if (dispX >= 0 && dispX < m_channel.Width
377 && dispY >= 0 && dispY < m_channel.Height)
378 {
379 m_channel[dispX, dispY] = channel[xx, yy];
380 }
381 }
382 }
383 }
384 }
385
386 private static Stream URIFetch(Uri uri) 359 private static Stream URIFetch(Uri uri)
387 { 360 {
388 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 361 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
index 469bd31..f660b8d 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using OpenSim.Framework; 28using OpenSim.Framework;
29using OpenMetaverse;
29 30
30namespace OpenSim.Region.Framework.Interfaces 31namespace OpenSim.Region.Framework.Interfaces
31{ 32{
@@ -56,5 +57,7 @@ namespace OpenSim.Region.Framework.Interfaces
56 ITerrainChannel MakeCopy(); 57 ITerrainChannel MakeCopy();
57 string SaveToXmlString(); 58 string SaveToXmlString();
58 void LoadFromXmlString(string data); 59 void LoadFromXmlString(string data);
60 // Merge some terrain into this channel
61 void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement);
59 } 62 }
60} 63}
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
index 189a30a..a6f5d98 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces
51 /// </param> 51 /// </param>
52 /// <param name="stream"></param> 52 /// <param name="stream"></param>
53 void LoadFromStream(string filename, Stream stream); 53 void LoadFromStream(string filename, Stream stream);
54 void LoadFromStream(string filename, Vector2 displacement, Stream stream); 54 void LoadFromStream(string filename, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement, Stream stream);
55 void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap); 55 void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap);
56 /// <summary> 56 /// <summary>
57 /// Save a terrain to a stream. 57 /// Save a terrain to a stream.
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index b4b1823..24709dc 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -36,6 +36,8 @@ using OpenSim.Data;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38 38
39using OpenMetaverse;
40
39using log4net; 41using log4net;
40 42
41namespace OpenSim.Region.Framework.Scenes 43namespace OpenSim.Region.Framework.Scenes
@@ -212,6 +214,76 @@ namespace OpenSim.Region.Framework.Scenes
212 sr.Close(); 214 sr.Close();
213 } 215 }
214 216
217 // ITerrainChannel.Merge
218 public void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement)
219 {
220 for (int xx = 0; xx < newTerrain.Width; xx++)
221 {
222 for (int yy = 0; yy < newTerrain.Height; yy++)
223 {
224 int dispX = (int)displacement.X;
225 int dispY = (int)displacement.Y;
226 float newHeight = (float)newTerrain[xx, yy] + displacement.Z;
227 if (radianRotation == 0)
228 {
229 // If no rotation, place the new height in the specified location
230 dispX += xx;
231 dispY += yy;
232 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
233 {
234 m_terrainData[dispX, dispY] = newHeight;
235 }
236 }
237 else
238 {
239 // If rotating, we have to smooth the result because the conversion
240 // to ints will mean heightmap entries will not get changed
241 // First compute the rotation location for the new height.
242 dispX += (int)(rotationDisplacement.X
243 + ((float)xx - rotationDisplacement.X) * Math.Cos(radianRotation)
244 - ((float)yy - rotationDisplacement.Y) * Math.Sin(radianRotation) );
245
246 dispY += (int)(rotationDisplacement.Y
247 + ((float)xx - rotationDisplacement.X) * Math.Sin(radianRotation)
248 + ((float)yy - rotationDisplacement.Y) * Math.Cos(radianRotation) );
249
250 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
251 {
252 float oldHeight = m_terrainData[dispX, dispY];
253 // Smooth the heights around this location if the old height is far from this one
254 for (int sxx = dispX - 2; sxx < dispX + 2; sxx++)
255 {
256 for (int syy = dispY - 2; syy < dispY + 2; syy++)
257 {
258 if (sxx >= 0 && sxx < m_terrainData.SizeX && syy >= 0 && syy < m_terrainData.SizeY)
259 {
260 if (sxx == dispX && syy == dispY)
261 {
262 // Set height for the exact rotated point
263 m_terrainData[dispX, dispY] = newHeight;
264 }
265 else
266 {
267 if (Math.Abs(m_terrainData[sxx, syy] - newHeight) > 1f)
268 {
269 // If the adjacent height is far off, force it to this height
270 m_terrainData[sxx, syy] = newHeight;
271 }
272 }
273 }
274 }
275 }
276 }
277
278 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
279 {
280 m_terrainData[dispX, dispY] = (float)newTerrain[xx, yy];
281 }
282 }
283 }
284 }
285 }
286
215 #endregion 287 #endregion
216 288
217 public TerrainChannel Copy() 289 public TerrainChannel Copy()