aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2014-02-02 11:17:49 -0800
committerRobert Adams2014-02-02 11:17:49 -0800
commit9c97fb8e127e91d48cf92eeed238cf80878e2286 (patch)
treea0d00a1707f45121137d210f18b8b9525cc3ab48
parentOverload INPCModule.CreateNPC() to allow agentID to be specified. Note: this ... (diff)
downloadopensim-SC_OLD-9c97fb8e127e91d48cf92eeed238cf80878e2286.zip
opensim-SC_OLD-9c97fb8e127e91d48cf92eeed238cf80878e2286.tar.gz
opensim-SC_OLD-9c97fb8e127e91d48cf92eeed238cf80878e2286.tar.bz2
opensim-SC_OLD-9c97fb8e127e91d48cf92eeed238cf80878e2286.tar.xz
Implement terrain merging in TerrainChannel.
Modify archiver to use terrain merging when loading oars. This makes displacement AND rotation properly work on terrain when loading oars. Especially useful when loading legacy region oars into large varregions.
-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()