diff options
author | Adam Frisby | 2008-04-06 13:48:28 +0000 |
---|---|---|
committer | Adam Frisby | 2008-04-06 13:48:28 +0000 |
commit | 996309a6e1ee47d96d81c0bdfdd5bfc27db66efd (patch) | |
tree | 9b9208a28969785a459e30de3ce9f260beb26201 /OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs | |
parent | * Fixed up some documentation (diff) | |
download | opensim-SC-996309a6e1ee47d96d81c0bdfdd5bfc27db66efd.zip opensim-SC-996309a6e1ee47d96d81c0bdfdd5bfc27db66efd.tar.gz opensim-SC-996309a6e1ee47d96d81c0bdfdd5bfc27db66efd.tar.bz2 opensim-SC-996309a6e1ee47d96d81c0bdfdd5bfc27db66efd.tar.xz |
* Various terrain engine fixes
* Includes patch #894 fixes for terrain load-tile
* Large number of other terrain fixes and new commands included.
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs | 215 |
1 files changed, 144 insertions, 71 deletions
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs index 88d7041..e9f1785 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs | |||
@@ -35,10 +35,9 @@ using OpenSim.Region.Environment.Interfaces; | |||
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | using OpenSim.Region.Environment.Modules.ModuleFramework; | 36 | using OpenSim.Region.Environment.Modules.ModuleFramework; |
37 | 37 | ||
38 | |||
39 | namespace OpenSim.Region.Environment.Modules.Terrain | 38 | namespace OpenSim.Region.Environment.Modules.Terrain |
40 | { | 39 | { |
41 | public class TerrainModule : IRegionModule , ITerrainTemp, ICommandableModule | 40 | public class TerrainModule : IRegionModule, ICommandableModule |
42 | { | 41 | { |
43 | public enum StandardTerrainEffects : byte | 42 | public enum StandardTerrainEffects : byte |
44 | { | 43 | { |
@@ -47,7 +46,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
47 | Lower = 2, | 46 | Lower = 2, |
48 | Smooth = 3, | 47 | Smooth = 3, |
49 | Noise = 4, | 48 | Noise = 4, |
50 | Revert = 5 | 49 | Revert = 5, |
50 | |||
51 | // Extended brushes | ||
52 | Erode = 255, | ||
53 | Weather = 254, | ||
54 | Olsen = 253 | ||
51 | } | 55 | } |
52 | 56 | ||
53 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 57 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
@@ -74,6 +78,9 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
74 | m_painteffects[StandardTerrainEffects.Noise] = new PaintBrushes.NoiseSphere(); | 78 | m_painteffects[StandardTerrainEffects.Noise] = new PaintBrushes.NoiseSphere(); |
75 | m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.FlattenSphere(); | 79 | m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.FlattenSphere(); |
76 | m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.RevertSphere(m_revert); | 80 | m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.RevertSphere(m_revert); |
81 | m_painteffects[StandardTerrainEffects.Erode] = new PaintBrushes.ErodeSphere(); | ||
82 | m_painteffects[StandardTerrainEffects.Weather] = new PaintBrushes.WeatherSphere(); | ||
83 | m_painteffects[StandardTerrainEffects.Olsen] = new PaintBrushes.OlsenSphere(); | ||
77 | 84 | ||
78 | // Area of effect selection effects | 85 | // Area of effect selection effects |
79 | m_floodeffects[StandardTerrainEffects.Raise] = new FloodBrushes.RaiseArea(); | 86 | m_floodeffects[StandardTerrainEffects.Raise] = new FloodBrushes.RaiseArea(); |
@@ -90,6 +97,11 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
90 | m_loaders[".raw"] = new FileLoaders.LLRAW(); | 97 | m_loaders[".raw"] = new FileLoaders.LLRAW(); |
91 | m_loaders[".jpg"] = new FileLoaders.JPEG(); | 98 | m_loaders[".jpg"] = new FileLoaders.JPEG(); |
92 | m_loaders[".jpeg"] = m_loaders[".jpg"]; | 99 | m_loaders[".jpeg"] = m_loaders[".jpg"]; |
100 | m_loaders[".bmp"] = new FileLoaders.BMP(); | ||
101 | m_loaders[".png"] = new FileLoaders.PNG(); | ||
102 | m_loaders[".gif"] = new FileLoaders.GIF(); | ||
103 | m_loaders[".tif"] = new FileLoaders.TIFF(); | ||
104 | m_loaders[".tiff"] = m_loaders[".tif"]; | ||
93 | } | 105 | } |
94 | 106 | ||
95 | public void UpdateRevertMap() | 107 | public void UpdateRevertMap() |
@@ -139,22 +151,26 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
139 | 151 | ||
140 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | 152 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) |
141 | { | 153 | { |
142 | fileStartX -= (int)m_scene.RegionInfo.RegionLocX; | 154 | int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; |
143 | fileStartY -= (int)m_scene.RegionInfo.RegionLocY; | 155 | int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; |
144 | 156 | ||
145 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 157 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) |
146 | { | 158 | { |
147 | if (filename.EndsWith(loader.Key)) | 159 | // this region is included in the tile request |
160 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | ||
148 | { | 161 | { |
149 | lock (m_scene) | 162 | if (filename.EndsWith(loader.Key)) |
150 | { | 163 | { |
151 | ITerrainChannel channel = loader.Value.LoadFile(filename, fileStartX, fileStartY, | 164 | lock (m_scene) |
152 | fileWidth, fileHeight, (int)Constants.RegionSize, (int)Constants.RegionSize); | 165 | { |
153 | m_scene.Heightmap = channel; | 166 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, |
154 | m_channel = channel; | 167 | fileWidth, fileHeight, (int)Constants.RegionSize, (int)Constants.RegionSize); |
155 | UpdateRevertMap(); | 168 | m_scene.Heightmap = channel; |
169 | m_channel = channel; | ||
170 | UpdateRevertMap(); | ||
171 | } | ||
172 | return; | ||
156 | } | 173 | } |
157 | return; | ||
158 | } | 174 | } |
159 | } | 175 | } |
160 | } | 176 | } |
@@ -181,7 +197,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
181 | public void Initialise(Scene scene, IConfigSource config) | 197 | public void Initialise(Scene scene, IConfigSource config) |
182 | { | 198 | { |
183 | m_scene = scene; | 199 | m_scene = scene; |
184 | m_scene.RegisterModuleInterface<ITerrainTemp>(this); | ||
185 | m_gConfig = config; | 200 | m_gConfig = config; |
186 | 201 | ||
187 | // Install terrain module in the simulator | 202 | // Install terrain module in the simulator |
@@ -222,7 +237,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
222 | private void InterfaceLoadFile(Object[] args) | 237 | private void InterfaceLoadFile(Object[] args) |
223 | { | 238 | { |
224 | LoadFromFile((string)args[0]); | 239 | LoadFromFile((string)args[0]); |
225 | SendUpdatedLayerData(); | 240 | CheckForTerrainUpdates(); |
226 | } | 241 | } |
227 | 242 | ||
228 | private void InterfaceLoadTileFile(Object[] args) | 243 | private void InterfaceLoadTileFile(Object[] args) |
@@ -232,7 +247,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
232 | (int)args[2], | 247 | (int)args[2], |
233 | (int)args[3], | 248 | (int)args[3], |
234 | (int)args[4]); | 249 | (int)args[4]); |
235 | SendUpdatedLayerData(); | 250 | CheckForTerrainUpdates(); |
236 | } | 251 | } |
237 | 252 | ||
238 | private void InterfaceSaveFile(Object[] args) | 253 | private void InterfaceSaveFile(Object[] args) |
@@ -240,6 +255,48 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
240 | SaveToFile((string)args[0]); | 255 | SaveToFile((string)args[0]); |
241 | } | 256 | } |
242 | 257 | ||
258 | private void InterfaceBakeTerrain(Object[] args) | ||
259 | { | ||
260 | UpdateRevertMap(); | ||
261 | } | ||
262 | |||
263 | private void InterfaceRevertTerrain(Object[] args) | ||
264 | { | ||
265 | int x, y; | ||
266 | for (x = 0; x < m_channel.Width; x++) | ||
267 | for (y = 0; y < m_channel.Height; y++) | ||
268 | m_channel[x, y] = m_revert[x, y]; | ||
269 | |||
270 | CheckForTerrainUpdates(); | ||
271 | } | ||
272 | |||
273 | private void InterfaceElevateTerrain(Object[] args) | ||
274 | { | ||
275 | int x, y; | ||
276 | for (x = 0; x < m_channel.Width; x++) | ||
277 | for (y = 0; y < m_channel.Height; y++) | ||
278 | m_channel[x, y] += (double)args[0]; | ||
279 | CheckForTerrainUpdates(); | ||
280 | } | ||
281 | |||
282 | private void InterfaceMultiplyTerrain(Object[] args) | ||
283 | { | ||
284 | int x, y; | ||
285 | for (x = 0; x < m_channel.Width; x++) | ||
286 | for (y = 0; y < m_channel.Height; y++) | ||
287 | m_channel[x, y] *= (double)args[0]; | ||
288 | CheckForTerrainUpdates(); | ||
289 | } | ||
290 | |||
291 | private void InterfaceLowerTerrain(Object[] args) | ||
292 | { | ||
293 | int x, y; | ||
294 | for (x = 0; x < m_channel.Width; x++) | ||
295 | for (y = 0; y < m_channel.Height; y++) | ||
296 | m_channel[x, y] -= (double)args[0]; | ||
297 | CheckForTerrainUpdates(); | ||
298 | } | ||
299 | |||
243 | private void InterfaceFillTerrain(Object[] args) | 300 | private void InterfaceFillTerrain(Object[] args) |
244 | { | 301 | { |
245 | int x, y; | 302 | int x, y; |
@@ -247,7 +304,33 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
247 | for (x = 0; x < m_channel.Width; x++) | 304 | for (x = 0; x < m_channel.Width; x++) |
248 | for (y = 0; y < m_channel.Height; y++) | 305 | for (y = 0; y < m_channel.Height; y++) |
249 | m_channel[x, y] = (double)args[0]; | 306 | m_channel[x, y] = (double)args[0]; |
250 | SendUpdatedLayerData(); | 307 | CheckForTerrainUpdates(); |
308 | } | ||
309 | |||
310 | private void InterfaceShowDebugStats(Object[] args) | ||
311 | { | ||
312 | double max = Double.MinValue; | ||
313 | double min = double.MaxValue; | ||
314 | double avg = 0; | ||
315 | double sum = 0; | ||
316 | |||
317 | int x, y; | ||
318 | for (x = 0; x < m_channel.Width; x++) | ||
319 | { | ||
320 | for (y = 0; y < m_channel.Height; y++) | ||
321 | { | ||
322 | sum += m_channel[x, y]; | ||
323 | if (max < m_channel[x, y]) | ||
324 | max = m_channel[x, y]; | ||
325 | if (min > m_channel[x, y]) | ||
326 | min = m_channel[x, y]; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | avg = sum / (m_channel.Height * m_channel.Width); | ||
331 | |||
332 | m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height); | ||
333 | m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum); | ||
251 | } | 334 | } |
252 | 335 | ||
253 | private void InterfaceEnableExperimentalBrushes(Object[] args) | 336 | private void InterfaceEnableExperimentalBrushes(Object[] args) |
@@ -264,6 +347,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
264 | } | 347 | } |
265 | } | 348 | } |
266 | 349 | ||
350 | private void InterfacePerformEffectTest(Object[] args) | ||
351 | { | ||
352 | Effects.CookieCutter cookie = new OpenSim.Region.Environment.Modules.Terrain.Effects.CookieCutter(); | ||
353 | cookie.RunEffect(m_channel); | ||
354 | } | ||
355 | |||
267 | private void InstallInterfaces() | 356 | private void InstallInterfaces() |
268 | { | 357 | { |
269 | // Load / Save | 358 | // Load / Save |
@@ -288,15 +377,39 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
288 | Command fillRegionCommand = new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); | 377 | Command fillRegionCommand = new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); |
289 | fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", "Double"); | 378 | fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", "Double"); |
290 | 379 | ||
291 | // Brushes | 380 | Command elevateCommand = new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount."); |
381 | elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double"); | ||
382 | |||
383 | Command lowerCommand = new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount."); | ||
384 | lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double"); | ||
385 | |||
386 | Command multiplyCommand = new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified."); | ||
387 | multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); | ||
388 | |||
389 | Command bakeRegionCommand = new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); | ||
390 | Command revertRegionCommand = new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); | ||
391 | |||
392 | // Debug | ||
393 | Command showDebugStatsCommand = new Command("stats", InterfaceShowDebugStats, "Shows some information about the regions heightmap for debugging purposes."); | ||
394 | |||
292 | Command experimentalBrushesCommand = new Command("newbrushes", InterfaceEnableExperimentalBrushes, "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); | 395 | Command experimentalBrushesCommand = new Command("newbrushes", InterfaceEnableExperimentalBrushes, "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); |
293 | experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); | 396 | experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); |
294 | 397 | ||
398 | // Effects | ||
399 | Command effectsTestCommand = new Command("test", InterfacePerformEffectTest, "Performs an effects module test"); | ||
400 | |||
295 | m_commander.RegisterCommand("load", loadFromFileCommand); | 401 | m_commander.RegisterCommand("load", loadFromFileCommand); |
296 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); | 402 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); |
297 | m_commander.RegisterCommand("save", saveToFileCommand); | 403 | m_commander.RegisterCommand("save", saveToFileCommand); |
298 | m_commander.RegisterCommand("fill", fillRegionCommand); | 404 | m_commander.RegisterCommand("fill", fillRegionCommand); |
405 | m_commander.RegisterCommand("elevate", elevateCommand); | ||
406 | m_commander.RegisterCommand("lower", lowerCommand); | ||
407 | m_commander.RegisterCommand("multiply", multiplyCommand); | ||
408 | m_commander.RegisterCommand("bake", bakeRegionCommand); | ||
409 | m_commander.RegisterCommand("revert", revertRegionCommand); | ||
299 | m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); | 410 | m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); |
411 | m_commander.RegisterCommand("test", effectsTestCommand); | ||
412 | m_commander.RegisterCommand("stats", showDebugStatsCommand); | ||
300 | 413 | ||
301 | // Add this to our scene so scripts can call these functions | 414 | // Add this to our scene so scripts can call these functions |
302 | m_scene.RegisterModuleCommander("Terrain", m_commander); | 415 | m_scene.RegisterModuleCommander("Terrain", m_commander); |
@@ -322,7 +435,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
322 | client.OnModifyTerrain += client_OnModifyTerrain; | 435 | client.OnModifyTerrain += client_OnModifyTerrain; |
323 | } | 436 | } |
324 | 437 | ||
325 | void SendUpdatedLayerData() | 438 | void CheckForTerrainUpdates() |
326 | { | 439 | { |
327 | bool shouldTaint = false; | 440 | bool shouldTaint = false; |
328 | float[] serialised = m_channel.GetFloatsSerialised(); | 441 | float[] serialised = m_channel.GetFloatsSerialised(); |
@@ -333,10 +446,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
333 | { | 446 | { |
334 | if (m_channel.Tainted(x, y)) | 447 | if (m_channel.Tainted(x, y)) |
335 | { | 448 | { |
336 | m_scene.ForEachClient(delegate(IClientAPI controller) | 449 | SendToClients(serialised, x, y); |
337 | { | ||
338 | controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); | ||
339 | }); | ||
340 | shouldTaint = true; | 450 | shouldTaint = true; |
341 | } | 451 | } |
342 | } | 452 | } |
@@ -347,6 +457,14 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
347 | } | 457 | } |
348 | } | 458 | } |
349 | 459 | ||
460 | private void SendToClients(float[] serialised, int x, int y) | ||
461 | { | ||
462 | m_scene.ForEachClient(delegate(IClientAPI controller) | ||
463 | { | ||
464 | controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); | ||
465 | }); | ||
466 | } | ||
467 | |||
350 | void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, float south, float east, IClientAPI remoteClient) | 468 | void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, float south, float east, IClientAPI remoteClient) |
351 | { | 469 | { |
352 | // Not a good permissions check, if in area mode, need to check the entire area. | 470 | // Not a good permissions check, if in area mode, need to check the entire area. |
@@ -364,7 +482,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
364 | 482 | ||
365 | if (usingTerrainModule) | 483 | if (usingTerrainModule) |
366 | { | 484 | { |
367 | SendUpdatedLayerData(); | 485 | CheckForTerrainUpdates(); |
368 | } | 486 | } |
369 | } | 487 | } |
370 | else | 488 | else |
@@ -401,7 +519,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
401 | 519 | ||
402 | if (usingTerrainModule) | 520 | if (usingTerrainModule) |
403 | { | 521 | { |
404 | SendUpdatedLayerData(); | 522 | CheckForTerrainUpdates(); |
405 | } | 523 | } |
406 | } | 524 | } |
407 | else | 525 | else |
@@ -412,51 +530,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
412 | } | 530 | } |
413 | } | 531 | } |
414 | 532 | ||
415 | public byte[] WriteJpegImage(string gradientmap) | ||
416 | { | ||
417 | byte[] imageData = null; | ||
418 | try | ||
419 | { | ||
420 | Bitmap bmp = TerrainToBitmap(gradientmap); | ||
421 | |||
422 | imageData = OpenJPEGNet.OpenJPEG.EncodeFromImage(bmp, true); | ||
423 | |||
424 | } | ||
425 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | ||
426 | { | ||
427 | Console.WriteLine("Failed generating terrain map: " + e.ToString()); | ||
428 | } | ||
429 | |||
430 | return imageData; | ||
431 | } | ||
432 | |||
433 | private Bitmap TerrainToBitmap(string gradientmap) | ||
434 | { | ||
435 | Bitmap gradientmapLd = new Bitmap(gradientmap); | ||
436 | |||
437 | int pallete = gradientmapLd.Height; | ||
438 | |||
439 | Bitmap bmp = new Bitmap(m_channel.Width, m_channel.Height); | ||
440 | Color[] colours = new Color[pallete]; | ||
441 | |||
442 | for (int i = 0; i < pallete; i++) | ||
443 | { | ||
444 | colours[i] = gradientmapLd.GetPixel(0, i); | ||
445 | } | ||
446 | |||
447 | TerrainChannel copy =(TerrainChannel) m_channel.MakeCopy(); | ||
448 | for (int y = 0; y < copy.Height; y++) | ||
449 | { | ||
450 | for (int x = 0; x < copy.Width; x++) | ||
451 | { | ||
452 | // 512 is the largest possible height before colours clamp | ||
453 | int colorindex = (int)(Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1)); | ||
454 | bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]); | ||
455 | } | ||
456 | } | ||
457 | return bmp; | ||
458 | } | ||
459 | |||
460 | public void PostInitialise() | 533 | public void PostInitialise() |
461 | { | 534 | { |
462 | InstallDefaultEffects(); | 535 | InstallDefaultEffects(); |