aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:22:29 +0000
committerAdam Frisby2008-04-30 21:22:29 +0000
commit4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6 (patch)
tree49dde0575502e89aeed428b4190c68306e929b69 /OpenSim/Region/Environment/Modules
parent* Previous commit managed to miss some files despite me hitting 'Select all'. (diff)
downloadopensim-SC_OLD-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.zip
opensim-SC_OLD-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.gz
opensim-SC_OLD-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.bz2
opensim-SC_OLD-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.xz
* Commiting a bunch of missed files.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Framework/Commander.cs308
-rw-r--r--OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs89
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs1008
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs86
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandObject.cs943
-rw-r--r--OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs37
-rw-r--r--OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs123
-rw-r--r--OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs53
-rw-r--r--OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs169
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs124
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs55
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs62
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs48
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs172
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs94
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs148
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs48
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs153
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs48
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs127
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs71
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs54
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs56
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs53
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs60
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs114
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs37
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs39
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs8
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs168
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs312
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs127
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs67
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs70
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs225
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs67
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs82
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs93
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs207
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs157
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs46
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs737
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs133
46 files changed, 6986 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Framework/Commander.cs b/OpenSim/Region/Environment/Modules/Framework/Commander.cs
new file mode 100644
index 0000000..6cf8298
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Framework/Commander.cs
@@ -0,0 +1,308 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35
36namespace OpenSim.Region.Environment.Modules.Framework
37{
38 /// <summary>
39 /// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s.
40 /// Used for console commands and script API generation
41 /// </summary>
42 public class Command : ICommand
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private List<CommandArgument> m_args = new List<CommandArgument>();
46
47 private Action<object[]> m_command;
48 private string m_help;
49 private string m_name;
50
51 public Command(string name, Action<Object[]> command, string help)
52 {
53 m_name = name;
54 m_command = command;
55 m_help = help;
56 }
57
58 #region ICommand Members
59
60 public void AddArgument(string name, string helptext, string type)
61 {
62 m_args.Add(new CommandArgument(name, helptext, type));
63 }
64
65 public string Name
66 {
67 get { return m_name; }
68 }
69
70 public string Help
71 {
72 get { return m_help; }
73 }
74
75 public Dictionary<string, string> Arguments
76 {
77 get
78 {
79 Dictionary<string, string> tmp = new Dictionary<string, string>();
80 foreach (CommandArgument arg in m_args)
81 {
82 tmp.Add(arg.Name, arg.ArgumentType);
83 }
84 return tmp;
85 }
86 }
87
88 public void ShowConsoleHelp()
89 {
90 m_log.Info("== " + Name + " ==");
91 m_log.Info(m_help);
92 m_log.Info("= Parameters =");
93 foreach (CommandArgument arg in m_args)
94 {
95 m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
96 m_log.Info("\t" + arg.HelpText);
97 }
98 }
99
100 public void Run(Object[] args)
101 {
102 Object[] cleanArgs = new Object[m_args.Count];
103
104 if (args.Length < cleanArgs.Length)
105 {
106 m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
107 ShowConsoleHelp();
108 return;
109 }
110 if (args.Length > cleanArgs.Length)
111 {
112 m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
113 return;
114 }
115
116 int i = 0;
117 foreach (Object arg in args)
118 {
119 if (string.IsNullOrEmpty(arg.ToString()))
120 {
121 m_log.Error("Empty arguments are not allowed");
122 return;
123 }
124 try
125 {
126 switch (m_args[i].ArgumentType)
127 {
128 case "String":
129 m_args[i].ArgumentValue = arg.ToString();
130 break;
131 case "Integer":
132 m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
133 break;
134 case "Double":
135 m_args[i].ArgumentValue = Double.Parse(arg.ToString());
136 break;
137 case "Boolean":
138 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
139 break;
140 default:
141 m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
142 break;
143 }
144 }
145 catch (FormatException)
146 {
147 m_log.Error("Argument number " + (i + 1) +
148 " (" + m_args[i].Name + ") must be a valid " +
149 m_args[i].ArgumentType.ToLower() + ".");
150 }
151 cleanArgs[i] = m_args[i].ArgumentValue;
152
153 i++;
154 }
155
156 m_command.Invoke(cleanArgs);
157 }
158
159 #endregion
160 }
161
162 /// <summary>
163 /// A single command argument, contains name, type and at runtime, value.
164 /// </summary>
165 public class CommandArgument
166 {
167 private string m_help;
168 private string m_name;
169 private string m_type;
170 private Object m_val;
171
172 public CommandArgument(string name, string help, string type)
173 {
174 m_name = name;
175 m_help = help;
176 m_type = type;
177 }
178
179 public string Name
180 {
181 get { return m_name; }
182 }
183
184 public string HelpText
185 {
186 get { return m_help; }
187 }
188
189 public string ArgumentType
190 {
191 get { return m_type; }
192 }
193
194 public Object ArgumentValue
195 {
196 get { return m_val; }
197 set { m_val = value; }
198 }
199 }
200
201 /// <summary>
202 /// A class to enable modules to register console and script commands, which enforces typing and valid input.
203 /// </summary>
204 public class Commander : ICommander
205 {
206 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
207 private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
208 private string m_name;
209
210 public Commander(string name)
211 {
212 m_name = name;
213 }
214
215 #region ICommander Members
216
217 public void RegisterCommand(string commandName, ICommand command)
218 {
219 m_commands[commandName] = command;
220 }
221
222 /// <summary>
223 /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
224 /// </summary>
225 /// <returns>Returns C# source code to create a binding</returns>
226 public string GenerateRuntimeAPI()
227 {
228 string classSrc = "\n\tpublic class " + m_name + " {\n";
229 foreach (ICommand com in m_commands.Values)
230 {
231 classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
232 foreach (KeyValuePair<string, string> arg in com.Arguments)
233 {
234 classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
235 }
236 classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
237 classSrc += " )\n\t{\n";
238 classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
239 int i = 0;
240 foreach (KeyValuePair<string, string> arg in com.Arguments)
241 {
242 classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
243 i++;
244 }
245 classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
246 classSrc += "\t}\n";
247 }
248 classSrc += "}\n";
249
250 return classSrc;
251 }
252
253 /// <summary>
254 /// Runs a specified function with attached arguments
255 /// *** <b>DO NOT CALL DIRECTLY.</b> ***
256 /// Call ProcessConsoleCommand instead if handling human input.
257 /// </summary>
258 /// <param name="function">The function name to call</param>
259 /// <param name="args">The function parameters</param>
260 public void Run(string function, object[] args)
261 {
262 m_commands[function].Run(args);
263 }
264
265 public void ProcessConsoleCommand(string function, string[] args)
266 {
267 if (m_commands.ContainsKey(function))
268 {
269 if (args.Length > 0 && args[0] == "help")
270 {
271 m_commands[function].ShowConsoleHelp();
272 }
273 else
274 {
275 m_commands[function].Run(args);
276 }
277 }
278 else
279 {
280 if (function != "help")
281 m_log.Error("Invalid command - No such command exists");
282 if (function == "api")
283 m_log.Info(GenerateRuntimeAPI());
284 ShowConsoleHelp();
285 }
286 }
287
288 #endregion
289
290 private void ShowConsoleHelp()
291 {
292 m_log.Info("===" + m_name + "===");
293 foreach (ICommand com in m_commands.Values)
294 {
295 m_log.Info("* " + com.Name + " - " + com.Help);
296 }
297 }
298
299 private string EscapeRuntimeAPICommand(string command)
300 {
301 command = command.Replace('-', '_');
302 StringBuilder tmp = new StringBuilder(command);
303 tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
304
305 return tmp.ToString();
306 }
307 }
308} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs b/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs
new file mode 100644
index 0000000..76bdae3
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Region.Environment.Interfaces;
31using OpenSim.Region.Environment.Modules.Framework;
32using OpenSim.Region.Environment.Scenes;
33
34namespace OpenSim.Region.Environment.Modules.Framework
35{
36 public class CommanderTestModule : IRegionModule, ICommandableModule
37 {
38 Commander m_commander = new Commander("CommanderTest");
39 Scene m_scene;
40
41 #region IRegionModule Members
42
43 public void Initialise(Scene scene, IConfigSource source)
44 {
45 m_scene = scene;
46 }
47
48 private void InterfaceHelloWorld(Object[] args)
49 {
50 Console.WriteLine("Hello World");
51 }
52
53 public void PostInitialise()
54 {
55 Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string");
56 testCommand.AddArgument("world", "Write world here", "string");
57
58 m_commander.RegisterCommand("hello", testCommand);
59
60 // Register me
61 m_scene.RegisterModuleCommander("commandertest", m_commander);
62 }
63
64 public void Close()
65 {
66 }
67
68 public string Name
69 {
70 get { return "CommanderTestModule"; }
71 }
72
73 public bool IsSharedModule
74 {
75 get { return false; }
76 }
77
78 #endregion
79
80 #region ICommandableModule Members
81
82 public ICommander CommandInterface
83 {
84 get { throw new NotImplementedException(); }
85 }
86
87 #endregion
88 }
89} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
new file mode 100644
index 0000000..cbea07a
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
@@ -0,0 +1,1008 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using Axiom.Math;
31using libsecondlife;
32using libsecondlife.Packets;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Physics.Manager;
37
38namespace OpenSim.Region.Environment.Modules.World.Land
39{
40 public class LandChannel : ILandChannel
41 {
42 #region Constants
43
44 //Land types set with flags in ParcelOverlay.
45 //Only one of these can be used.
46 public const byte LAND_TYPE_PUBLIC = (byte)0; //Equals 00000000
47 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001
48 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010
49 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011
50 public const byte LAND_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100
51 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101
52
53 //Flags that when set, a border on the given side will be placed
54 //NOTE: North and East is assumable by the west and south sides (if land to east has a west border, then I have an east border; etc)
55 //This took forever to figure out -- jeesh. /blame LL for even having to send these
56 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000
57 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000
58
59 //RequestResults (I think these are right, they seem to work):
60 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
61 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
62
63 //ParcelSelectObjects
64 public const int LAND_SELECT_OBJECTS_OWNER = 2;
65 public const int LAND_SELECT_OBJECTS_GROUP = 4;
66 public const int LAND_SELECT_OBJECTS_OTHER = 8;
67
68 //These are other constants. Yay!
69 public const int START_LAND_LOCAL_ID = 1;
70
71 public const float BAN_LINE_SAFETY_HIEGHT = 100;
72
73 #endregion
74
75 private Scene m_scene;
76
77 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>();
78 private int lastLandLocalID = START_LAND_LOCAL_ID - 1;
79 private int[,] landIDList = new int[64, 64];
80
81 private bool landPrimCountTainted = false;
82
83 private bool m_allowedForcefulBans = true;
84 public bool allowedForcefulBans
85 {
86 get
87 {
88 return m_allowedForcefulBans;
89 }
90 set
91 {
92 m_allowedForcefulBans = value;
93 }
94 }
95
96 public LandChannel(Scene scene)
97 {
98 m_scene = scene;
99 landIDList.Initialize();
100 }
101 #region Land Object From Storage Functions
102
103 public void IncomingLandObjectsFromStorage(List<LandData> data)
104 {
105 for (int i = 0; i < data.Count; i++)
106 {
107 //try
108 //{
109 IncomingLandObjectFromStorage(data[i]);
110 //}
111 //catch (Exception ex)
112 //{
113 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString());
114 //throw ex;
115 //}
116 }
117 //foreach (LandData parcel in data)
118 //{
119 // IncomingLandObjectFromStorage(parcel);
120 //}
121 }
122
123 public void IncomingLandObjectFromStorage(LandData data)
124 {
125 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene);
126 new_land.landData = data.Copy();
127 new_land.setLandBitmapFromByteArray();
128 addLandObject(new_land);
129 }
130
131 public void NoLandDataFromStorage()
132 {
133 resetSimLandObjects();
134 }
135
136 #endregion
137
138 #region Parcel Add/Remove/Get/Create
139
140 /// <summary>
141 /// Creates a basic Parcel object without an owner (a zeroed key)
142 /// </summary>
143 /// <returns></returns>
144 public ILandObject createBaseLand()
145 {
146 return new LandObject(LLUUID.Zero, false, m_scene);
147 }
148
149 /// <summary>
150 /// Adds a land object to the stored list and adds them to the landIDList to what they own
151 /// </summary>
152 /// <param name="new_land">The land object being added</param>
153 public ILandObject addLandObject(ILandObject new_land)
154 {
155 lastLandLocalID++;
156 new_land.landData.localID = lastLandLocalID;
157 landList.Add(lastLandLocalID, (LandObject)new_land.Copy());
158
159
160 bool[,] landBitmap = new_land.getLandBitmap();
161 int x, y;
162 for (x = 0; x < 64; x++)
163 {
164 for (y = 0; y < 64; y++)
165 {
166 if (landBitmap[x, y])
167 {
168 landIDList[x, y] = lastLandLocalID;
169 }
170 }
171 }
172 landList[lastLandLocalID].forceUpdateLandInfo();
173 m_scene.EventManager.TriggerLandObjectAdded(new_land);
174 return new_land;
175 }
176
177 /// <summary>
178 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList
179 /// </summary>
180 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
181 public void removeLandObject(int local_id)
182 {
183 int x, y;
184 for (x = 0; x < 64; x++)
185 {
186 for (y = 0; y < 64; y++)
187 {
188 if (landIDList[x, y] == local_id)
189 {
190 return;
191 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
192 }
193 }
194 }
195
196 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID);
197 landList.Remove(local_id);
198 }
199
200 public void updateLandObject(int local_id, LandData newData)
201 {
202 if (landList.ContainsKey(local_id))
203 {
204 landList[local_id].landData = newData.Copy();
205 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landList[local_id]);
206 }
207 }
208
209 private void performFinalLandJoin(ILandObject master, ILandObject slave)
210 {
211 int x, y;
212 bool[,] landBitmapSlave = slave.getLandBitmap();
213 for (x = 0; x < 64; x++)
214 {
215 for (y = 0; y < 64; y++)
216 {
217 if (landBitmapSlave[x, y])
218 {
219 landIDList[x, y] = master.landData.localID;
220 }
221 }
222 }
223
224 removeLandObject(slave.landData.localID);
225 updateLandObject(master.landData.localID, master.landData);
226 }
227
228 /// <summary>
229 /// Get the land object at the specified point
230 /// </summary>
231 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
232 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
233 /// <returns>Land object at the point supplied</returns>
234 public ILandObject getLandObject(float x_float, float y_float)
235 {
236 int x;
237 int y;
238
239 try
240 {
241 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0)));
242 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0)));
243 }
244 catch (OverflowException)
245 {
246 return null;
247 }
248
249 if (x >= 64 || y >= 64 || x < 0 || y < 0)
250 {
251 return null;
252 }
253 else
254 {
255 return landList[landIDList[x, y]];
256 }
257 }
258
259 public ILandObject getLandObject(int parcelLocalID)
260 {
261 lock (landList)
262 {
263 if (landList.ContainsKey(parcelLocalID))
264 {
265 return landList[parcelLocalID];
266 }
267 }
268 return null;
269 }
270
271 public ILandObject getLandObject(int x, int y)
272 {
273 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
274 {
275 // These exceptions here will cause a lot of complaints from the users specifically because
276 // they happen every time at border crossings
277 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
278 }
279 else
280 {
281 return landList[landIDList[x / 4, y / 4]];
282 }
283 }
284
285 #endregion
286
287 #region Parcel Modification
288
289 /// <summary>
290 /// Subdivides a piece of land
291 /// </summary>
292 /// <param name="start_x">West Point</param>
293 /// <param name="start_y">South Point</param>
294 /// <param name="end_x">East Point</param>
295 /// <param name="end_y">North Point</param>
296 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
297 /// <returns>Returns true if successful</returns>
298 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
299 {
300 //First, lets loop through the points and make sure they are all in the same peice of land
301 //Get the land object at start
302 ILandObject startLandObject = null;
303 try
304 {
305 startLandObject = getLandObject(start_x, start_y);
306 }
307 catch (Exception)
308 {
309 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y);
310 }
311 if (startLandObject == null) return false; //No such land object at the beginning
312
313 //Loop through the points
314 try
315 {
316 int totalX = end_x - start_x;
317 int totalY = end_y - start_y;
318 int x, y;
319 for (y = 0; y < totalY; y++)
320 {
321 for (x = 0; x < totalX; x++)
322 {
323 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y);
324 if (tempLandObject == null) return false; //No such land object at that point
325 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no
326 }
327 }
328 }
329 catch (Exception)
330 {
331 return false; //Exception. For now, lets skip subdivision
332 }
333
334 //If we are still here, then they are subdividing within one piece of land
335 //Check owner
336 if (startLandObject.landData.ownerID != attempting_user_id)
337 {
338 return false; //They cant do this!
339 }
340
341 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
342 ILandObject newLand = startLandObject.Copy();
343 newLand.landData.landName = "Subdivision of " + newLand.landData.landName;
344 newLand.landData.globalID = LLUUID.Random();
345
346 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y));
347
348 //Now, lets set the subdivision area of the original to false
349 int startLandObjectIndex = startLandObject.landData.localID;
350 landList[startLandObjectIndex].setLandBitmap(
351 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false));
352 landList[startLandObjectIndex].forceUpdateLandInfo();
353
354 setPrimsTainted();
355
356 //Now add the new land object
357 ILandObject result = addLandObject(newLand);
358 updateLandObject(startLandObject.landData.localID, startLandObject.landData);
359 result.sendLandUpdateToAvatarsOverMe();
360
361
362 return true;
363 }
364
365 /// <summary>
366 /// Join 2 land objects together
367 /// </summary>
368 /// <param name="start_x">x value in first piece of land</param>
369 /// <param name="start_y">y value in first piece of land</param>
370 /// <param name="end_x">x value in second peice of land</param>
371 /// <param name="end_y">y value in second peice of land</param>
372 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param>
373 /// <returns>Returns true if successful</returns>
374 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
375 {
376 end_x -= 4;
377 end_y -= 4;
378
379 List<ILandObject> selectedLandObjects = new List<ILandObject>();
380 int stepXSelected = 0;
381 int stepYSelected = 0;
382 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
383 {
384 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
385 {
386 ILandObject p = null;
387 try
388 {
389 p = getLandObject(stepXSelected, stepYSelected);
390 }
391 catch (Exception)
392 {
393 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected);
394 }
395 if (p != null)
396 {
397 if (!selectedLandObjects.Contains(p))
398 {
399 selectedLandObjects.Add(p);
400 }
401 }
402 }
403 }
404 ILandObject masterLandObject = selectedLandObjects[0];
405 selectedLandObjects.RemoveAt(0);
406
407
408 if (selectedLandObjects.Count < 1)
409 {
410 return false; //Only one piece of land selected
411 }
412 if (masterLandObject.landData.ownerID != attempting_user_id)
413 {
414 return false; //Not the same owner
415 }
416 foreach (ILandObject p in selectedLandObjects)
417 {
418 if (p.landData.ownerID != masterLandObject.landData.ownerID)
419 {
420 return false; //Over multiple users. TODO: make this just ignore this piece of land?
421 }
422 }
423 foreach (ILandObject slaveLandObject in selectedLandObjects)
424 {
425 landList[masterLandObject.landData.localID].setLandBitmap(
426 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap()));
427 performFinalLandJoin(masterLandObject, slaveLandObject);
428 }
429
430
431 setPrimsTainted();
432
433 masterLandObject.sendLandUpdateToAvatarsOverMe();
434
435 return true;
436 }
437
438 public void resetAllLandPrimCounts()
439 {
440 foreach (LandObject p in landList.Values)
441 {
442 p.resetLandPrimCounts();
443 }
444 }
445
446 public void setPrimsTainted()
447 {
448 landPrimCountTainted = true;
449 }
450
451 public bool isLandPrimCountTainted()
452 {
453 return landPrimCountTainted;
454 }
455
456 public void addPrimToLandPrimCounts(SceneObjectGroup obj)
457 {
458 LLVector3 position = obj.AbsolutePosition;
459 ILandObject landUnderPrim = getLandObject(position.X, position.Y);
460 if (landUnderPrim != null)
461 {
462 landUnderPrim.addPrimToCount(obj);
463 }
464 }
465
466 public void removePrimFromLandPrimCounts(SceneObjectGroup obj)
467 {
468 foreach (LandObject p in landList.Values)
469 {
470 p.removePrimFromCount(obj);
471 }
472 }
473
474 public void finalizeLandPrimCountUpdate()
475 {
476 //Get Simwide prim count for owner
477 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>();
478 foreach (LandObject p in landList.Values)
479 {
480 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID))
481 {
482 List<LandObject> tempList = new List<LandObject>();
483 tempList.Add(p);
484 landOwnersAndParcels.Add(p.landData.ownerID, tempList);
485 }
486 else
487 {
488 landOwnersAndParcels[p.landData.ownerID].Add(p);
489 }
490 }
491
492 foreach (LLUUID owner in landOwnersAndParcels.Keys)
493 {
494 int simArea = 0;
495 int simPrims = 0;
496 foreach (LandObject p in landOwnersAndParcels[owner])
497 {
498 simArea += p.landData.area;
499 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims +
500 p.landData.selectedPrims;
501 }
502
503 foreach (LandObject p in landOwnersAndParcels[owner])
504 {
505 p.landData.simwideArea = simArea;
506 p.landData.simwidePrims = simPrims;
507 }
508 }
509 }
510
511 public void updateLandPrimCounts()
512 {
513 foreach (EntityBase obj in m_scene.Entities.Values)
514 {
515 if (obj is SceneObjectGroup)
516 {
517 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup)obj);
518 }
519 }
520 }
521
522 public void performParcelPrimCountUpdate()
523 {
524 resetAllLandPrimCounts();
525 m_scene.EventManager.TriggerParcelPrimCountUpdate();
526 finalizeLandPrimCountUpdate();
527 landPrimCountTainted = false;
528 }
529 #endregion
530
531 #region Parcel Updating
532
533 /// <summary>
534 /// Where we send the ParcelOverlay packet to the client
535 /// </summary>
536 /// <param name="remote_client">The object representing the client</param>
537 public void sendParcelOverlay(IClientAPI remote_client)
538 {
539 const int LAND_BLOCKS_PER_PACKET = 1024;
540 int x, y = 0;
541 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
542 int byteArrayCount = 0;
543 int sequenceID = 0;
544 ParcelOverlayPacket packet;
545
546 for (y = 0; y < 64; y++)
547 {
548 for (x = 0; x < 64; x++)
549 {
550 byte tempByte = (byte)0; //This represents the byte for the current 4x4
551 ILandObject currentParcelBlock = null;
552
553 try
554 {
555 currentParcelBlock = getLandObject(x * 4, y * 4);
556 }
557 catch (Exception)
558 {
559 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4));
560 }
561
562
563 if (currentParcelBlock != null)
564 {
565 if (currentParcelBlock.landData.ownerID == remote_client.AgentId)
566 {
567 //Owner Flag
568 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER);
569 }
570 else if (currentParcelBlock.landData.salePrice > 0 &&
571 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero ||
572 currentParcelBlock.landData.authBuyerID == remote_client.AgentId))
573 {
574 //Sale Flag
575 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE);
576 }
577 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero)
578 {
579 //Public Flag
580 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC);
581 }
582 else
583 {
584 //Other Flag
585 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER);
586 }
587
588
589 //Now for border control
590 try
591 {
592 ILandObject westParcel = null;
593 ILandObject southParcel = null;
594 if (x > 0)
595 {
596 westParcel = getLandObject((x - 1) * 4, y * 4);
597 }
598 if (y > 0)
599 {
600 southParcel = getLandObject(x * 4, (y - 1) * 4);
601 }
602
603 if (x == 0)
604 {
605 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
606 }
607 else if (westParcel != null && westParcel != currentParcelBlock)
608 {
609 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
610 }
611
612 if (y == 0)
613 {
614 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
615 }
616 else if (southParcel != null && southParcel != currentParcelBlock)
617 {
618 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
619 }
620
621 byteArray[byteArrayCount] = tempByte;
622 byteArrayCount++;
623 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
624 {
625 byteArrayCount = 0;
626 packet = (ParcelOverlayPacket)PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
627 packet.ParcelData.Data = byteArray;
628 packet.ParcelData.SequenceID = sequenceID;
629 remote_client.OutPacket((Packet)packet, ThrottleOutPacketType.Task);
630 sequenceID++;
631 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
632 }
633 }
634 catch (Exception)
635 {
636 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message);
637 }
638 }
639 }
640 }
641 }
642
643 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
644 bool snap_selection, IClientAPI remote_client)
645 {
646 //Get the land objects within the bounds
647 List<ILandObject> temp = new List<ILandObject>();
648 int x, y, i;
649 int inc_x = end_x - start_x;
650 int inc_y = end_y - start_y;
651 for (x = 0; x < inc_x; x++)
652 {
653 for (y = 0; y < inc_y; y++)
654 {
655
656 ILandObject currentParcel = null;
657 try
658 {
659 currentParcel = getLandObject(start_x + x, start_y + y);
660 }
661 catch (Exception)
662 {
663 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y));
664 }
665 if (currentParcel != null)
666 {
667 if (!temp.Contains(currentParcel))
668 {
669 currentParcel.forceUpdateLandInfo();
670 temp.Add(currentParcel);
671 }
672 }
673 }
674 }
675
676 int requestResult = LAND_RESULT_SINGLE;
677 if (temp.Count > 1)
678 {
679 requestResult = LAND_RESULT_MULTIPLE;
680 }
681
682 for (i = 0; i < temp.Count; i++)
683 {
684 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
685 }
686
687
688 sendParcelOverlay(remote_client);
689 }
690
691 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
692 {
693 if (landList.ContainsKey(packet.ParcelData.LocalID))
694 {
695 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client);
696
697 }
698 }
699
700 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
701 {
702 subdivide(west, south, east, north, remote_client.AgentId);
703 }
704
705 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
706 {
707 join(west, south, east, north, remote_client.AgentId);
708 }
709
710 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
711 {
712 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
713 }
714
715 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
716 {
717 landList[local_id].sendLandObjectOwners(remote_client);
718 }
719
720 #endregion
721
722 /// <summary>
723 /// Resets the sim to the default land object (full sim piece of land owned by the default user)
724 /// </summary>
725 public void resetSimLandObjects()
726 {
727 //Remove all the land objects in the sim and add a blank, full sim land object set to public
728 landList.Clear();
729 lastLandLocalID = START_LAND_LOCAL_ID - 1;
730 landIDList.Initialize();
731
732 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene);
733
734 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
735 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
736
737 addLandObject(fullSimParcel);
738 }
739
740 public List<ILandObject> parcelsNearPoint(LLVector3 position)
741 {
742 List<ILandObject> parcelsNear = new List<ILandObject>();
743 int x, y;
744 for (x = -4; x <= 4; x += 4)
745 {
746 for (y = -4; y <= 4; y += 4)
747 {
748 ILandObject check = getLandObject(position.X + x, position.Y + y);
749 if (check != null)
750 {
751 if (!parcelsNear.Contains(check))
752 {
753 parcelsNear.Add(check);
754 }
755 }
756 }
757 }
758
759 return parcelsNear;
760 }
761
762 public void sendYouAreBannedNotice(ScenePresence avatar)
763 {
764 if (allowedForcefulBans)
765 {
766 avatar.ControllingClient.SendAlertMessage(
767 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers");
768
769 avatar.PhysicsActor.Position =
770 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y,
771 avatar.lastKnownAllowedPosition.z);
772 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0);
773 }
774 else
775 {
776 avatar.ControllingClient.SendAlertMessage(
777 "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim! <3 OpenSim Developers");
778 }
779 }
780
781 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
782 {
783 if (m_scene.RegionInfo.RegionID == regionID)
784 {
785 if (landList[localLandID] != null)
786 {
787 ILandObject parcelAvatarIsEntering = landList[localLandID];
788 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT)
789 {
790 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID))
791 {
792 sendYouAreBannedNotice(avatar);
793 }
794 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID))
795 {
796 avatar.ControllingClient.SendAlertMessage(
797 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers");
798 }
799 else
800 {
801 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
802 }
803 }
804 else
805 {
806 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
807 }
808 }
809 }
810 }
811
812 public void sendOutNearestBanLine(IClientAPI avatar)
813 {
814 List<ScenePresence> avatars = m_scene.GetAvatars();
815 foreach (ScenePresence presence in avatars)
816 {
817 if (presence.UUID == avatar.AgentId)
818 {
819
820 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition);
821 foreach (ILandObject checkBan in checkLandParcels)
822 {
823 if (checkBan.isBannedFromLand(avatar.AgentId))
824 {
825 checkBan.sendLandProperties(-30000, false, (int)ParcelManager.ParcelResult.Single, avatar);
826 return; //Only send one
827 }
828 else if (checkBan.isRestrictedFromLand(avatar.AgentId))
829 {
830 checkBan.sendLandProperties(-40000, false, (int)ParcelManager.ParcelResult.Single, avatar);
831 return; //Only send one
832 }
833 }
834 return;
835 }
836 }
837 }
838
839 public void sendLandUpdate(ScenePresence avatar, bool force)
840 {
841 ILandObject over = null;
842 try
843 {
844 over = getLandObject((int)Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
845 (int)Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
846 }
847 catch (Exception)
848 {
849 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y));
850 }
851
852 if (over != null)
853 {
854 if (force)
855 {
856 if (!avatar.IsChildAgent)
857 {
858 over.sendLandUpdateToClient(avatar.ControllingClient);
859 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
860 m_scene.RegionInfo.RegionID);
861 }
862 }
863
864 if (avatar.currentParcelUUID != over.landData.globalID)
865 {
866 if (!avatar.IsChildAgent)
867 {
868 over.sendLandUpdateToClient(avatar.ControllingClient);
869 avatar.currentParcelUUID = over.landData.globalID;
870 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
871 m_scene.RegionInfo.RegionID);
872 }
873 }
874 }
875 }
876 public void sendLandUpdate(ScenePresence avatar)
877 {
878 sendLandUpdate(avatar, false);
879
880 }
881 public void handleSignificantClientMovement(IClientAPI remote_client)
882 {
883 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId);
884
885 if (clientAvatar != null)
886 {
887 sendLandUpdate(clientAvatar);
888 sendOutNearestBanLine(remote_client);
889 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
890 if (parcel != null)
891 {
892 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
893 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
894 {
895 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID);
896 //They are going below the safety line!
897 if (!parcel.isBannedFromLand(clientAvatar.UUID))
898 {
899 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
900 }
901 }
902 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
903 parcel.isBannedFromLand(clientAvatar.UUID))
904 {
905 sendYouAreBannedNotice(clientAvatar);
906 }
907 }
908 }
909 }
910
911 public void handleAnyClientMovement(ScenePresence avatar)
912 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance.
913 {
914 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
915 if (over != null)
916 {
917 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT)
918 {
919 avatar.lastKnownAllowedPosition =
920 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
921 }
922 }
923 }
924
925
926 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
927 int landLocalID, IClientAPI remote_client)
928 {
929 if (landList.ContainsKey(landLocalID))
930 {
931 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client);
932 }
933 }
934
935 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID,
936 List<ParcelManager.ParcelAccessEntry> entries,
937 IClientAPI remote_client)
938 {
939 if (landList.ContainsKey(landLocalID))
940 {
941 if (agentID == landList[landLocalID].landData.ownerID)
942 {
943 landList[landLocalID].updateAccessList(flags, entries, remote_client);
944 }
945 }
946 else
947 {
948 Console.WriteLine("INVALID LOCAL LAND ID");
949 }
950 }
951
952 // If the economy has been validated by the economy module,
953 // and land has been validated as well, this method transfers
954 // the land ownership
955
956 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e)
957 {
958 if (e.economyValidated && e.landValidated)
959 {
960 lock (landList)
961 {
962 if (landList.ContainsKey(e.parcelLocalID))
963 {
964 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea);
965 return;
966 }
967 }
968 }
969 }
970
971 // After receiving a land buy packet, first the data needs to
972 // be validated. This method validates the right to buy the
973 // parcel
974
975 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e)
976 {
977 if (e.landValidated == false)
978 {
979 ILandObject lob = null;
980 lock (landList)
981 {
982 if (landList.ContainsKey(e.parcelLocalID))
983 {
984 lob = landList[e.parcelLocalID];
985 }
986 }
987 if (lob != null)
988 {
989 LLUUID AuthorizedID = lob.landData.authBuyerID;
990 int saleprice = lob.landData.salePrice;
991 LLUUID pOwnerID = lob.landData.ownerID;
992
993 bool landforsale = ((lob.landData.landFlags & (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0);
994 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale)
995 {
996 lock (e)
997 {
998 e.parcelOwnerID = pOwnerID;
999 e.landValidated = true;
1000
1001 }
1002
1003 }
1004 }
1005 }
1006 }
1007 }
1008} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
new file mode 100644
index 0000000..c5ffdca
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nini.Config;
29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Modules.World.Land;
31using OpenSim.Region.Environment.Scenes;
32
33namespace OpenSim.Region.Environment.Modules.World.Land
34{
35 public class LandManagementModule : IRegionModule
36 {
37 private LandChannel landChannel;
38 private Scene m_scene;
39
40 #region IRegionModule Members
41
42 public void Initialise(Scene scene, IConfigSource source)
43 {
44 m_scene = scene;
45 landChannel = new LandChannel(scene);
46
47 m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
48 m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
49 m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
50 m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
51 m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
52 m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
53
54 lock (m_scene)
55 {
56 m_scene.LandChannel = (ILandChannel)landChannel;
57 }
58 }
59
60 public void PostInitialise()
61 {
62
63 }
64
65 public void Close()
66 {
67
68 }
69
70 public string Name
71 {
72 get { return "LandManagementModule"; }
73 }
74
75 public bool IsSharedModule
76 {
77 get { return false; }
78 }
79
80
81
82
83
84 #endregion
85 }
86} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
new file mode 100644
index 0000000..693c55d
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
@@ -0,0 +1,943 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using libsecondlife;
32using libsecondlife.Packets;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Modules.World.Land;
37using OpenSim.Region.Environment.Scenes;
38
39namespace OpenSim.Region.Environment.Modules.World.Land
40{
41 /// <summary>
42 /// Keeps track of a specific piece of land's information
43 /// </summary>
44 public class LandObject : ILandObject
45 {
46 #region Member Variables
47
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 protected LandData m_landData = new LandData();
51 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
52 protected Scene m_scene;
53
54 private bool[,] m_landBitmap = new bool[64,64];
55
56 public bool[,] landBitmap
57 {
58 get
59 {
60 return m_landBitmap;
61 }
62 set
63 {
64 m_landBitmap = value;
65 }
66 }
67
68 #endregion
69
70 #region ILandObject Members
71
72 public LandData landData
73 {
74 get
75 {
76 return m_landData;
77 }
78
79 set
80 {
81 m_landData = value;
82 }
83 }
84
85 public LLUUID regionUUID
86 {
87 get { return m_scene.RegionInfo.RegionID; }
88 }
89
90 #endregion
91
92
93 #region Constructors
94
95 public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene)
96 {
97 m_scene = scene;
98 landData.ownerID = owner_id;
99 landData.isGroupOwned = is_group_owned;
100 }
101
102 #endregion
103
104 #region Member Functions
105
106 #region General Functions
107
108 /// <summary>
109 /// Checks to see if this land object contains a point
110 /// </summary>
111 /// <param name="x"></param>
112 /// <param name="y"></param>
113 /// <returns>Returns true if the piece of land contains the specified point</returns>
114 public bool containsPoint(int x, int y)
115 {
116 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
117 {
118 return (landBitmap[x/4, y/4] == true);
119 }
120 else
121 {
122 return false;
123 }
124 }
125
126 public ILandObject Copy()
127 {
128 ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene);
129
130 //Place all new variables here!
131 newLand.landBitmap = (bool[,]) (landBitmap.Clone());
132 newLand.landData = landData.Copy();
133
134 return newLand;
135 }
136
137 #endregion
138
139 #region Packet Request Handling
140
141 /// <summary>
142 /// Sends land properties as requested
143 /// </summary>
144 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
145 /// <param name="snap_selection">Bool sent by client for them to use</param>
146 /// <param name="remote_client">Object representing the client</param>
147 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result,
148 IClientAPI remote_client)
149 {
150 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties);
151 // TODO: don't create new blocks if recycling an old packet
152
153 updatePacket.ParcelData.AABBMax = landData.AABBMax;
154 updatePacket.ParcelData.AABBMin = landData.AABBMin;
155 updatePacket.ParcelData.Area = landData.area;
156 updatePacket.ParcelData.AuctionID = landData.auctionID;
157 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented
158
159 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray;
160
161 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc);
162 updatePacket.ParcelData.Category = (byte) landData.category;
163 updatePacket.ParcelData.ClaimDate = landData.claimDate;
164 updatePacket.ParcelData.ClaimPrice = landData.claimPrice;
165 updatePacket.ParcelData.GroupID = landData.groupID;
166 updatePacket.ParcelData.GroupPrims = landData.groupPrims;
167 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned;
168 updatePacket.ParcelData.LandingType = (byte) landData.landingType;
169 updatePacket.ParcelData.LocalID = landData.localID;
170 if (landData.area > 0)
171 {
172 updatePacket.ParcelData.MaxPrims =
173 Convert.ToInt32(
174 Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*m_scene.objectCapacity*
175 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
176 }
177 else
178 {
179 updatePacket.ParcelData.MaxPrims = 0;
180 }
181 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale;
182 updatePacket.ParcelData.MediaID = landData.mediaID;
183 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL);
184 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL);
185 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName);
186 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
187 updatePacket.ParcelData.OtherCount = 0; //unemplemented
188 updatePacket.ParcelData.OtherPrims = landData.otherPrims;
189 updatePacket.ParcelData.OwnerID = landData.ownerID;
190 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims;
191 updatePacket.ParcelData.ParcelFlags = landData.landFlags;
192 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor;
193 updatePacket.ParcelData.PassHours = landData.passHours;
194 updatePacket.ParcelData.PassPrice = landData.passPrice;
195 updatePacket.ParcelData.PublicCount = 0; //unemplemented
196
197 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags;
198 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) >
199 0);
200 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) >
201 0);
202 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) >
203 0);
204 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) >
205 0);
206
207 updatePacket.ParcelData.RentPrice = 0;
208 updatePacket.ParcelData.RequestResult = request_result;
209 updatePacket.ParcelData.SalePrice = landData.salePrice;
210 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims;
211 updatePacket.ParcelData.SelfCount = 0; //unemplemented
212 updatePacket.ParcelData.SequenceID = sequence_id;
213 if (landData.simwideArea > 0)
214 {
215 updatePacket.ParcelData.SimWideMaxPrims =
216 Convert.ToInt32(
217 Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
218 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
219 }
220 else
221 {
222 updatePacket.ParcelData.SimWideMaxPrims = 0;
223 }
224 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims;
225 updatePacket.ParcelData.SnapSelection = snap_selection;
226 updatePacket.ParcelData.SnapshotID = landData.snapshotID;
227 updatePacket.ParcelData.Status = (byte) landData.landStatus;
228 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims +
229 landData.selectedPrims;
230 updatePacket.ParcelData.UserLocation = landData.userLocation;
231 updatePacket.ParcelData.UserLookAt = landData.userLookAt;
232 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task);
233 }
234
235 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
236 {
237 if (remote_client.AgentId == landData.ownerID)
238 {
239 //Needs later group support
240 LandData newData = landData.Copy();
241 newData.authBuyerID = packet.ParcelData.AuthBuyerID;
242 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category;
243 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
244 newData.groupID = packet.ParcelData.GroupID;
245 newData.landingType = packet.ParcelData.LandingType;
246 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
247 newData.mediaID = packet.ParcelData.MediaID;
248 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
249 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
250 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
251 newData.landFlags = packet.ParcelData.ParcelFlags;
252 newData.passHours = packet.ParcelData.PassHours;
253 newData.passPrice = packet.ParcelData.PassPrice;
254 newData.salePrice = packet.ParcelData.SalePrice;
255 newData.snapshotID = packet.ParcelData.SnapshotID;
256 newData.userLocation = packet.ParcelData.UserLocation;
257 newData.userLookAt = packet.ParcelData.UserLookAt;
258
259 m_scene.LandChannel.updateLandObject(landData.localID, newData);
260
261 sendLandUpdateToAvatarsOverMe();
262 }
263 }
264 public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
265 {
266 LandData newData = landData.Copy();
267 newData.ownerID = avatarID;
268 newData.groupID = groupID;
269 newData.isGroupOwned = groupOwned;
270 //newData.auctionID = AuctionID;
271 newData.claimDate = Util.UnixTimeSinceEpoch();
272 newData.claimPrice = claimprice;
273 newData.salePrice = 0;
274 newData.authBuyerID = LLUUID.Zero;
275 newData.landFlags &= ~(uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects);
276 m_scene.LandChannel.updateLandObject(landData.localID, newData);
277
278 sendLandUpdateToAvatarsOverMe();
279 }
280
281 public bool isEitherBannedOrRestricted(LLUUID avatar)
282 {
283 if (isBannedFromLand(avatar))
284 {
285 return true;
286 }
287 else if (isRestrictedFromLand(avatar))
288 {
289 return true;
290 }
291 return false;
292 }
293
294 public bool isBannedFromLand(LLUUID avatar)
295 {
296 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
297 {
298 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
299 entry.AgentID = avatar;
300 entry.Flags = ParcelManager.AccessList.Ban;
301 entry.Time = new DateTime();
302 if (landData.parcelAccessList.Contains(entry))
303 {
304 //They are banned, so lets send them a notice about this parcel
305 return true;
306 }
307 }
308 return false;
309 }
310
311 public bool isRestrictedFromLand(LLUUID avatar)
312 {
313 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
314 {
315 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
316 entry.AgentID = avatar;
317 entry.Flags = ParcelManager.AccessList.Access;
318 entry.Time = new DateTime();
319 if (!landData.parcelAccessList.Contains(entry))
320 {
321 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
322 return true;
323 }
324 }
325 return false;
326 }
327
328 public void sendLandUpdateToClient(IClientAPI remote_client)
329 {
330 sendLandProperties(0, false, 0, remote_client);
331 }
332
333 public void sendLandUpdateToAvatarsOverMe()
334 {
335 List<ScenePresence> avatars = m_scene.GetAvatars();
336 ILandObject over = null;
337 for (int i = 0; i < avatars.Count; i++)
338 {
339 try
340 {
341 over =
342 m_scene.LandChannel.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))),
343 (int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y))));
344 }
345 catch (Exception)
346 {
347 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y));
348 }
349
350 if (over != null)
351 {
352 if (over.landData.localID == landData.localID)
353 {
354 sendLandUpdateToClient(avatars[i].ControllingClient);
355 }
356 }
357 }
358 }
359
360 #endregion
361
362 #region AccessList Functions
363
364 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag)
365 {
366 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
367 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList)
368 {
369 if (entry.Flags == flag)
370 {
371 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
372
373 listBlock.Flags = (uint) 0;
374 listBlock.ID = entry.AgentID;
375 listBlock.Time = 0;
376
377 list.Add(listBlock);
378 }
379 }
380
381 if (list.Count == 0)
382 {
383 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
384
385 listBlock.Flags = (uint) 0;
386 listBlock.ID = LLUUID.Zero;
387 listBlock.Time = 0;
388
389 list.Add(listBlock);
390 }
391 return list.ToArray();
392 }
393
394 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
395 IClientAPI remote_client)
396 {
397 ParcelAccessListReplyPacket replyPacket;
398
399 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both)
400 {
401 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
402 replyPacket.Data.AgentID = agentID;
403 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access;
404 replyPacket.Data.LocalID = landData.localID;
405 replyPacket.Data.SequenceID = 0;
406
407 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access);
408 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
409 }
410
411 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both)
412 {
413 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
414 replyPacket.Data.AgentID = agentID;
415 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban;
416 replyPacket.Data.LocalID = landData.localID;
417 replyPacket.Data.SequenceID = 0;
418
419 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban);
420 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
421 }
422 }
423
424 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
425 {
426 LandData newData = landData.Copy();
427
428 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero)
429 {
430 entries.Clear();
431 }
432
433 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
434 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList)
435 {
436 if (entry.Flags == (ParcelManager.AccessList) flags)
437 {
438 toRemove.Add(entry);
439 }
440 }
441
442 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
443 {
444 newData.parcelAccessList.Remove(entry);
445 }
446 foreach (ParcelManager.ParcelAccessEntry entry in entries)
447 {
448 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
449 temp.AgentID = entry.AgentID;
450 temp.Time = new DateTime(); //Pointless? Yes.
451 temp.Flags = (ParcelManager.AccessList) flags;
452
453 if (!newData.parcelAccessList.Contains(temp))
454 {
455 newData.parcelAccessList.Add(temp);
456 }
457 }
458
459 m_scene.LandChannel.updateLandObject(landData.localID, newData);
460 }
461
462 #endregion
463
464 #region Update Functions
465
466 /// <summary>
467 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
468 /// </summary>
469 private void updateAABBAndAreaValues()
470 {
471 int min_x = 64;
472 int min_y = 64;
473 int max_x = 0;
474 int max_y = 0;
475 int tempArea = 0;
476 int x, y;
477 for (x = 0; x < 64; x++)
478 {
479 for (y = 0; y < 64; y++)
480 {
481 if (landBitmap[x, y] == true)
482 {
483 if (min_x > x) min_x = x;
484 if (min_y > y) min_y = y;
485 if (max_x < x) max_x = x;
486 if (max_y < y) max_y = y;
487 tempArea += 16; //16sqm peice of land
488 }
489 }
490 }
491 int tx = min_x * 4;
492 if (tx > 255)
493 tx = 255;
494 int ty = min_y * 4;
495 if (ty > 255)
496 ty = 255;
497 landData.AABBMin =
498 new LLVector3((float)(min_x * 4), (float)(min_y * 4),
499 (float)m_scene.Heightmap[tx, ty]);
500
501 tx = max_x * 4;
502 if (tx > 255)
503 tx = 255;
504 ty = max_y * 4;
505 if (ty > 255)
506 ty = 255;
507 landData.AABBMax =
508 new LLVector3((float)(max_x * 4), (float)(max_y * 4),
509 (float)m_scene.Heightmap[tx, ty]);
510 landData.area = tempArea;
511 }
512
513 public void updateLandBitmapByteArray()
514 {
515 landData.landBitmapByteArray = convertLandBitmapToBytes();
516 }
517
518 /// <summary>
519 /// Update all settings in land such as area, bitmap byte array, etc
520 /// </summary>
521 public void forceUpdateLandInfo()
522 {
523 updateAABBAndAreaValues();
524 updateLandBitmapByteArray();
525 }
526
527 public void setLandBitmapFromByteArray()
528 {
529 landBitmap = convertBytesToLandBitmap();
530 }
531
532 #endregion
533
534 #region Land Bitmap Functions
535
536 /// <summary>
537 /// Sets the land's bitmap manually
538 /// </summary>
539 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
540 public void setLandBitmap(bool[,] bitmap)
541 {
542 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
543 {
544 //Throw an exception - The bitmap is not 64x64
545 //throw new Exception("Error: Invalid Parcel Bitmap");
546 }
547 else
548 {
549 //Valid: Lets set it
550 landBitmap = bitmap;
551 forceUpdateLandInfo();
552 }
553 }
554
555 /// <summary>
556 /// Gets the land's bitmap manually
557 /// </summary>
558 /// <returns></returns>
559 public bool[,] getLandBitmap()
560 {
561 return landBitmap;
562 }
563
564 /// <summary>
565 /// Converts the land bitmap to a packet friendly byte array
566 /// </summary>
567 /// <returns></returns>
568 private byte[] convertLandBitmapToBytes()
569 {
570 byte[] tempConvertArr = new byte[512];
571 byte tempByte = 0;
572 int x, y, i, byteNum = 0;
573 i = 0;
574 for (y = 0; y < 64; y++)
575 {
576 for (x = 0; x < 64; x++)
577 {
578 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8));
579 if (i%8 == 0)
580 {
581 tempConvertArr[byteNum] = tempByte;
582 tempByte = (byte) 0;
583 i = 0;
584 byteNum++;
585 }
586 }
587 }
588 return tempConvertArr;
589 }
590
591 private bool[,] convertBytesToLandBitmap()
592 {
593 bool[,] tempConvertMap = new bool[64,64];
594 tempConvertMap.Initialize();
595 byte tempByte = 0;
596 int x = 0, y = 0, i = 0, bitNum = 0;
597 for (i = 0; i < 512; i++)
598 {
599 tempByte = landData.landBitmapByteArray[i];
600 for (bitNum = 0; bitNum < 8; bitNum++)
601 {
602 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
603 tempConvertMap[x, y] = bit;
604 x++;
605 if (x > 63)
606 {
607 x = 0;
608 y++;
609 }
610 }
611 }
612 return tempConvertMap;
613 }
614
615 /// <summary>
616 /// Full sim land object creation
617 /// </summary>
618 /// <returns></returns>
619 public bool[,] basicFullRegionLandBitmap()
620 {
621 return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize);
622 }
623
624 /// <summary>
625 /// Used to modify the bitmap between the x and y points. Points use 64 scale
626 /// </summary>
627 /// <param name="start_x"></param>
628 /// <param name="start_y"></param>
629 /// <param name="end_x"></param>
630 /// <param name="end_y"></param>
631 /// <returns></returns>
632 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
633 {
634 bool[,] tempBitmap = new bool[64,64];
635 tempBitmap.Initialize();
636
637 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
638 return tempBitmap;
639 }
640
641 /// <summary>
642 /// Change a land bitmap at within a square and set those points to a specific value
643 /// </summary>
644 /// <param name="land_bitmap"></param>
645 /// <param name="start_x"></param>
646 /// <param name="start_y"></param>
647 /// <param name="end_x"></param>
648 /// <param name="end_y"></param>
649 /// <param name="set_value"></param>
650 /// <returns></returns>
651 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
652 bool set_value)
653 {
654 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
655 {
656 //Throw an exception - The bitmap is not 64x64
657 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
658 }
659
660 int x, y;
661 for (y = 0; y < 64; y++)
662 {
663 for (x = 0; x < 64; x++)
664 {
665 if (x >= start_x/4 && x < end_x/4
666 && y >= start_y/4 && y < end_y/4)
667 {
668 land_bitmap[x, y] = set_value;
669 }
670 }
671 }
672 return land_bitmap;
673 }
674
675 /// <summary>
676 /// Join the true values of 2 bitmaps together
677 /// </summary>
678 /// <param name="bitmap_base"></param>
679 /// <param name="bitmap_add"></param>
680 /// <returns></returns>
681 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
682 {
683 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
684 {
685 //Throw an exception - The bitmap is not 64x64
686 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
687 }
688 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
689 {
690 //Throw an exception - The bitmap is not 64x64
691 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
692 }
693
694 int x, y;
695 for (y = 0; y < 64; y++)
696 {
697 for (x = 0; x < 64; x++)
698 {
699 if (bitmap_add[x, y])
700 {
701 bitmap_base[x, y] = true;
702 }
703 }
704 }
705 return bitmap_base;
706 }
707
708 #endregion
709
710 #region Object Select and Object Owner Listing
711
712 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
713 {
714 List<uint> resultLocalIDs = new List<uint>();
715 foreach (SceneObjectGroup obj in primsOverMe)
716 {
717 if (obj.LocalId > 0)
718 {
719 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID)
720 {
721 resultLocalIDs.Add(obj.LocalId);
722 }
723 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support
724 // {
725 // }
726 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
727 obj.OwnerID != remote_client.AgentId)
728 {
729 resultLocalIDs.Add(obj.LocalId);
730 }
731 }
732 }
733
734
735 bool firstCall = true;
736 int MAX_OBJECTS_PER_PACKET = 251;
737 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
738 // TODO: don't create new blocks if recycling an old packet
739 ForceObjectSelectPacket.DataBlock[] data;
740 while (resultLocalIDs.Count > 0)
741 {
742 if (firstCall)
743 {
744 pack._Header.ResetList = true;
745 firstCall = false;
746 }
747 else
748 {
749 pack._Header.ResetList = false;
750 }
751
752 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
753 {
754 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
755 }
756 else
757 {
758 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
759 }
760
761 int i;
762 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
763 {
764 data[i] = new ForceObjectSelectPacket.DataBlock();
765 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
766 resultLocalIDs.RemoveAt(0);
767 }
768 pack.Data = data;
769 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task);
770 }
771 }
772
773 /// <summary>
774 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
775 /// aggreagete details such as the number of prims.
776 ///
777 /// </summary>
778 /// <param name="remote_client">
779 /// A <see cref="IClientAPI"/>
780 /// </param>
781 public void sendLandObjectOwners(IClientAPI remote_client)
782 {
783 Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>();
784 ParcelObjectOwnersReplyPacket pack
785 = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
786 // TODO: don't create new blocks if recycling an old packet
787
788 foreach (SceneObjectGroup obj in primsOverMe)
789 {
790 try
791 {
792 if (!primCount.ContainsKey(obj.OwnerID))
793 {
794 primCount.Add(obj.OwnerID, 0);
795 }
796 }
797 catch (NullReferenceException)
798 {
799 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
800 }
801 try
802 {
803 primCount[obj.OwnerID] += obj.PrimCount;
804 }
805 catch (KeyNotFoundException)
806 {
807 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
808 }
809 }
810
811 int notifyCount = primCount.Count;
812
813 if (notifyCount > 0)
814 {
815 if (notifyCount > 32)
816 {
817 m_log.InfoFormat(
818 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
819 + " - a developer might want to investigate whether this is a hard limit", 32);
820
821 notifyCount = 32;
822 }
823
824 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
825 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
826
827 int num = 0;
828 foreach (LLUUID owner in primCount.Keys)
829 {
830 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
831 dataBlock[num].Count = primCount[owner];
832 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
833 dataBlock[num].OnlineStatus = true; //TODO: fix me later
834 dataBlock[num].OwnerID = owner;
835
836 num++;
837
838 if (num >= notifyCount)
839 {
840 break;
841 }
842 }
843
844 pack.Data = dataBlock;
845 }
846
847 remote_client.OutPacket(pack, ThrottleOutPacketType.Task);
848 }
849
850 public Dictionary<LLUUID, int> getLandObjectOwners()
851 {
852 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
853 foreach (SceneObjectGroup obj in primsOverMe)
854 {
855 if (!ownersAndCount.ContainsKey(obj.OwnerID))
856 {
857 ownersAndCount.Add(obj.OwnerID, 0);
858 }
859 ownersAndCount[obj.OwnerID] += obj.PrimCount;
860 }
861 return ownersAndCount;
862 }
863
864 #endregion
865
866 #region Object Returning
867
868 public void returnObject(SceneObjectGroup obj)
869 {
870 }
871
872 public void returnLandObjects(int type, LLUUID owner)
873 {
874 }
875
876 #endregion
877
878 #region Object Adding/Removing from Parcel
879
880 public void resetLandPrimCounts()
881 {
882 landData.groupPrims = 0;
883 landData.ownerPrims = 0;
884 landData.otherPrims = 0;
885 landData.selectedPrims = 0;
886 primsOverMe.Clear();
887 }
888
889 public void addPrimToCount(SceneObjectGroup obj)
890 {
891 LLUUID prim_owner = obj.OwnerID;
892 int prim_count = obj.PrimCount;
893
894 if (obj.IsSelected)
895 {
896 landData.selectedPrims += prim_count;
897 }
898 else
899 {
900 if (prim_owner == landData.ownerID)
901 {
902 landData.ownerPrims += prim_count;
903 }
904 else
905 {
906 landData.otherPrims += prim_count;
907 }
908 }
909
910 primsOverMe.Add(obj);
911 }
912
913 public void removePrimFromCount(SceneObjectGroup obj)
914 {
915 if (primsOverMe.Contains(obj))
916 {
917 LLUUID prim_owner = obj.OwnerID;
918 int prim_count = obj.PrimCount;
919
920 if (prim_owner == landData.ownerID)
921 {
922 landData.ownerPrims -= prim_count;
923 }
924 else if (prim_owner == landData.groupID)
925 {
926 landData.groupPrims -= prim_count;
927 }
928 else
929 {
930 landData.otherPrims -= prim_count;
931 }
932
933 primsOverMe.Remove(obj);
934 }
935 }
936
937 #endregion
938
939 #endregion
940
941
942 }
943} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs
new file mode 100644
index 0000000..fc3f75d
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Scenes;
29
30namespace OpenSim.Region.Environment.Modules.ExportSerialiser
31{
32 internal interface IFileSerialiser
33 {
34 string WriteToFile(Scene scene, string dir);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs
new file mode 100644
index 0000000..0ea2f30
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using OpenSim.Region.Environment.Scenes;
30
31namespace OpenSim.Region.Environment.Modules.ExportSerialiser
32{
33 public interface IRegionSerialiser
34 {
35 List<string> SerialiseRegion(Scene scene, string saveDir);
36 }
37} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs
new file mode 100644
index 0000000..c14ae57
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.IO;
30using System.IO.Compression;
31using System.Text;
32using System.Xml;
33using OpenSim.Region.Environment.Scenes;
34
35namespace OpenSim.Region.Environment.Modules.ExportSerialiser
36{
37 internal class SerialiseObjects : IFileSerialiser
38 {
39 #region IFileSerialiser Members
40
41 public string WriteToFile(Scene scene, string dir)
42 {
43 string targetFileName = dir + "objects.xml";
44
45 SaveSerialisedToFile(targetFileName, scene);
46
47 return "objects.xml";
48 }
49
50 #endregion
51
52 public void SaveSerialisedToFile(string fileName, Scene scene)
53 {
54 string xmlstream = GetObjectXml(scene);
55
56 MemoryStream stream = ReformatXmlString(xmlstream);
57
58 stream.Seek(0, SeekOrigin.Begin);
59 CreateXmlFile(stream, fileName);
60
61 stream.Seek(0, SeekOrigin.Begin);
62 CreateCompressedXmlFile(stream, fileName);
63 }
64
65 private static MemoryStream ReformatXmlString(string xmlstream)
66 {
67 MemoryStream stream = new MemoryStream();
68 XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8);
69 XmlDocument doc = new XmlDocument();
70
71 doc.LoadXml(xmlstream);
72 formatter.Formatting = Formatting.Indented;
73 doc.WriteContentTo(formatter);
74 formatter.Flush();
75 return stream;
76 }
77
78 private static string GetObjectXml(Scene scene)
79 {
80 string xmlstream = "<scene>";
81
82 List<EntityBase> EntityList = scene.GetEntities();
83 List<string> EntityXml = new List<string>();
84
85 foreach (EntityBase ent in EntityList)
86 {
87 if (ent is SceneObjectGroup)
88 {
89 EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2());
90 }
91 }
92 EntityXml.Sort();
93
94 foreach (string xml in EntityXml)
95 xmlstream += xml;
96
97 xmlstream += "</scene>";
98 return xmlstream;
99 }
100
101 private static void CreateXmlFile(MemoryStream xmlStream, string fileName)
102 {
103 FileStream objectsFile = new FileStream(fileName, FileMode.Create);
104
105 xmlStream.WriteTo(objectsFile);
106 objectsFile.Flush();
107 objectsFile.Close();
108 }
109
110 private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName)
111 {
112 #region GZip Compressed Version
113 FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create);
114 MemoryStream gzipMSStream = new MemoryStream();
115 GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress);
116 xmlStream.WriteTo(gzipStream);
117 gzipMSStream.WriteTo(objectsFileCompressed);
118 objectsFileCompressed.Flush();
119 objectsFileCompressed.Close();
120 #endregion
121 }
122 }
123} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs
new file mode 100644
index 0000000..03824e8
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Modules.World.Terrain;
29using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
30using OpenSim.Region.Environment.Scenes;
31
32namespace OpenSim.Region.Environment.Modules.ExportSerialiser
33{
34 internal class SerialiseTerrain : IFileSerialiser
35 {
36 #region IFileSerialiser Members
37
38 public string WriteToFile(Scene scene, string dir)
39 {
40 ITerrainLoader fileSystemExporter = new RAW32();
41 string targetFileName = dir + "heightmap.r32";
42
43 lock (scene.Heightmap)
44 {
45 fileSystemExporter.SaveFile(targetFileName, scene.Heightmap);
46 }
47
48 return "heightmap.r32";
49 }
50
51 #endregion
52 }
53} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs
new file mode 100644
index 0000000..b626f16
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs
@@ -0,0 +1,169 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using Nini.Config;
32using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Modules.ExportSerialiser;
34using OpenSim.Region.Environment.Modules.Framework;
35using OpenSim.Region.Environment.Scenes;
36
37namespace OpenSim.Region.Environment.Modules.World.Serialiser
38{
39 public class SerialiserModule : IRegionModule, IRegionSerialiser
40 {
41 private Commander m_commander = new Commander("Export");
42 private List<Scene> m_regions = new List<Scene>();
43 private string m_savedir = "exports" + "/";
44 private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>();
45
46 #region IRegionModule Members
47
48 public void Initialise(Scene scene, IConfigSource source)
49 {
50 scene.RegisterModuleCommander("Export", m_commander);
51 scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
52 scene.RegisterModuleInterface<IRegionSerialiser>(this);
53
54 lock (m_regions)
55 {
56 m_regions.Add(scene);
57 }
58 }
59
60 public void PostInitialise()
61 {
62 lock (m_serialisers)
63 {
64 m_serialisers.Add(new SerialiseTerrain());
65 m_serialisers.Add(new SerialiseObjects());
66 }
67
68 LoadCommanderCommands();
69 }
70
71 public void Close()
72 {
73 m_regions.Clear();
74 }
75
76 public string Name
77 {
78 get { return "ExportSerialisationModule"; }
79 }
80
81 public bool IsSharedModule
82 {
83 get { return true; }
84 }
85
86 #endregion
87
88 #region IRegionSerialiser Members
89
90 public List<string> SerialiseRegion(Scene scene, string saveDir)
91 {
92 List<string> results = new List<string>();
93
94 if (!Directory.Exists(saveDir))
95 {
96 Directory.CreateDirectory(saveDir);
97 }
98
99 lock (m_serialisers)
100 {
101 foreach (IFileSerialiser serialiser in m_serialisers)
102 {
103 results.Add(serialiser.WriteToFile(scene, saveDir));
104 }
105 }
106
107 TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT");
108 regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName);
109 regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString());
110 regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString());
111 regionInfoWriter.WriteLine("Serialise Version: 0.1");
112 regionInfoWriter.Close();
113
114 TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest");
115 foreach (string line in results)
116 {
117 manifestWriter.WriteLine(line);
118 }
119 manifestWriter.Close();
120
121 return results;
122 }
123
124 #endregion
125
126 private void EventManager_OnPluginConsole(string[] args)
127 {
128 if (args[0] == "export")
129 {
130 string[] tmpArgs = new string[args.Length - 2];
131 int i = 0;
132 for (i = 2; i < args.Length; i++)
133 tmpArgs[i - 2] = args[i];
134
135 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
136 }
137 }
138
139 private void InterfaceSaveRegion(Object[] args)
140 {
141 foreach (Scene region in m_regions)
142 {
143 if (region.RegionInfo.RegionName == (string) args[0])
144 {
145 List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
146 }
147 }
148 }
149
150 private void InterfaceSaveAllRegions(Object[] args)
151 {
152 foreach (Scene region in m_regions)
153 {
154 List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
155 }
156 }
157
158 private void LoadCommanderCommands()
159 {
160 Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory.");
161 serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String");
162
163 Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory.");
164
165 m_commander.RegisterCommand("save", serialiseSceneCommand);
166 m_commander.RegisterCommand("save-all", serialiseAllScenesCommand);
167 }
168 }
169} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs
new file mode 100644
index 0000000..731326e
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs
@@ -0,0 +1,124 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using OpenSim.Region.Environment.Interfaces;
29using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
30using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
33{
34 internal class CookieCutter : ITerrainEffect
35 {
36 #region ITerrainEffect Members
37
38 public void RunEffect(ITerrainChannel map)
39 {
40 SmoothArea smooth = new SmoothArea();
41 ITerrainPaintableEffect eroder = new WeatherSphere();
42
43 bool[,] cliffMask = new bool[map.Width,map.Height];
44 bool[,] channelMask = new bool[map.Width,map.Height];
45 bool[,] smoothMask = new bool[map.Width,map.Height];
46
47 Console.WriteLine("S1");
48
49 // Step one, generate rough mask
50 int x, y;
51 for (x = 0; x < map.Width; x++)
52 {
53 for (y = 0; y < map.Height; y++)
54 {
55 Console.Write(".");
56 smoothMask[x, y] = true;
57
58 // Start underwater
59 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
60 // Add a little height. (terrain should now be above water, mostly.)
61 map[x, y] += 20;
62
63 int channelsX = 4;
64 int channelWidth = (map.Width / channelsX / 4);
65 int channelsY = 4;
66 int channelHeight = (map.Height / channelsY / 4);
67
68 SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
69 SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
70 }
71 }
72
73 Console.WriteLine("S2");
74 //smooth.FloodEffect(map, smoothMask, 4.0);
75
76 Console.WriteLine("S3");
77 for (x = 0; x < map.Width; x++)
78 {
79 for (y = 0; y < map.Height; y++)
80 {
81 if (cliffMask[x, y] == true)
82 eroder.PaintEffect(map, x, y, 4, 0.1);
83 }
84 }
85
86 for (x = 0; x < map.Width; x += 2)
87 {
88 for (y = 0; y < map.Height; y += 2)
89 {
90 if (map[x, y] < 0.1)
91 map[x, y] = 0.1;
92 if (map[x, y] > 256)
93 map[x, y] = 256;
94 }
95 }
96 //smooth.FloodEffect(map, smoothMask, 4.0);
97 }
98
99 #endregion
100
101 private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth,
102 int mapSize, int rp)
103 {
104 for (int i = 0; i < numChannels; i++)
105 {
106 double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
107
108 if (distanceToLine < channelWidth)
109 {
110 if (channelMask[x, y])
111 return;
112
113 // Remove channels
114 map[x, y] -= 10;
115 channelMask[x, y] = true;
116 }
117 if (distanceToLine < 1)
118 {
119 cliffMask[x, y] = true;
120 }
121 }
122 }
123 }
124} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs
new file mode 100644
index 0000000..9c35d4e
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using OpenSim.Framework;
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
31{
32 internal class DefaultTerrainGenerator : ITerrainEffect
33 {
34 #region ITerrainEffect Members
35
36 public void RunEffect(ITerrainChannel map)
37 {
38 int x, y;
39 for (x = 0; x < map.Width; x++)
40 {
41 for (y = 0; y < map.Height; y++)
42 {
43 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
44 double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
45 if (map[x, y] < spherFac)
46 {
47 map[x, y] = spherFac;
48 }
49 }
50 }
51 }
52
53 #endregion
54 }
55} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs
new file mode 100644
index 0000000..4705dad
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
32{
33 /// <summary>
34 /// A generic windows bitmap loader.
35 /// Should be capable of handling 24-bit RGB images.
36 ///
37 /// Uses the System.Drawing filesystem loader.
38 /// </summary>
39 internal class BMP : GenericSystemDrawing
40 {
41 /// <summary>
42 /// Exports a file to a image on the disk using a System.Drawing exporter.
43 /// </summary>
44 /// <param name="filename">The target filename</param>
45 /// <param name="map">The terrain channel being saved</param>
46 public override void SaveFile(string filename, ITerrainChannel map)
47 {
48 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
49
50 colours.Save(filename, ImageFormat.Bmp);
51 }
52
53 /// <summary>
54 /// The human readable version of the file format(s) this loader handles
55 /// </summary>
56 /// <returns></returns>
57 public override string ToString()
58 {
59 return "BMP";
60 }
61 }
62} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs
new file mode 100644
index 0000000..1dd923a
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
33{
34 internal class GIF : GenericSystemDrawing
35 {
36 public override void SaveFile(string filename, ITerrainChannel map)
37 {
38 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
39
40 colours.Save(filename, ImageFormat.Gif);
41 }
42
43 public override string ToString()
44 {
45 return "GIF";
46 }
47 }
48} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
new file mode 100644
index 0000000..b5e6bd9
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -0,0 +1,172 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using System.Drawing.Imaging;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
34{
35 /// <summary>
36 /// A virtual class designed to have methods overloaded,
37 /// this class provides an interface for a generic image
38 /// saving and loading mechanism, but does not specify the
39 /// format. It should not be insubstantiated directly.
40 /// </summary>
41 public class GenericSystemDrawing : ITerrainLoader
42 {
43 #region ITerrainLoader Members
44
45 public string FileExtension
46 {
47 get { return ".gsd"; }
48 }
49
50 /// <summary>
51 /// Loads a file from a specified filename on the disk,
52 /// parses the image using the System.Drawing parsers
53 /// then returns a terrain channel. Values are
54 /// returned based on HSL brightness between 0m and 128m
55 /// </summary>
56 /// <param name="filename">The target image to load</param>
57 /// <returns>A terrain channel generated from the image.</returns>
58 public virtual ITerrainChannel LoadFile(string filename)
59 {
60 Bitmap file = new Bitmap(filename);
61
62 ITerrainChannel retval = new TerrainChannel(file.Width, file.Height);
63
64 int x, y;
65 for (x = 0; x < file.Width; x++)
66 {
67 for (y = 0; y < file.Height; y++)
68 {
69 retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128;
70 }
71 }
72
73 return retval;
74 }
75
76 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
77 {
78 throw new NotImplementedException();
79 }
80
81 /// <summary>
82 /// Exports a file to a image on the disk using a System.Drawing exporter.
83 /// </summary>
84 /// <param name="filename">The target filename</param>
85 /// <param name="map">The terrain channel being saved</param>
86 public virtual void SaveFile(string filename, ITerrainChannel map)
87 {
88 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
89
90 colours.Save(filename, ImageFormat.Png);
91 }
92
93 #endregion
94
95 public override string ToString()
96 {
97 return "SYS.DRAWING";
98 }
99
100 /// <summary>
101 /// Protected method, generates a grayscale bitmap
102 /// image from a specified terrain channel.
103 /// </summary>
104 /// <param name="map">The terrain channel to export to bitmap</param>
105 /// <returns>A System.Drawing.Bitmap containing a grayscale image</returns>
106 protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
107 {
108 Bitmap bmp = new Bitmap(map.Width, map.Height);
109
110 int pallete = 256;
111
112 Color[] grays = new Color[pallete];
113 for (int i = 0; i < grays.Length; i++)
114 {
115 grays[i] = Color.FromArgb(i, i, i);
116 }
117
118 for (int y = 0; y < map.Height; y++)
119 {
120 for (int x = 0; x < map.Width; x++)
121 {
122 // 512 is the largest possible height before colours clamp
123 int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1));
124
125 // Handle error conditions
126 if (colorindex > pallete - 1 || colorindex < 0)
127 bmp.SetPixel(x, map.Height - y - 1, Color.Red);
128 else
129 bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
130 }
131 }
132 return bmp;
133 }
134
135 /// <summary>
136 /// Protected method, generates a coloured bitmap
137 /// image from a specified terrain channel.
138 /// </summary>
139 /// <param name="map">The terrain channel to export to bitmap</param>
140 /// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
141 protected Bitmap CreateBitmapFromMap(ITerrainChannel map)
142 {
143 Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
144
145 int pallete = gradientmapLd.Height;
146
147 Bitmap bmp = new Bitmap(map.Width, map.Height);
148 Color[] colours = new Color[pallete];
149
150 for (int i = 0; i < pallete; i++)
151 {
152 colours[i] = gradientmapLd.GetPixel(0, i);
153 }
154
155 for (int y = 0; y < map.Height; y++)
156 {
157 for (int x = 0; x < map.Width; x++)
158 {
159 // 512 is the largest possible height before colours clamp
160 int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
161
162 // Handle error conditions
163 if (colorindex > pallete - 1 || colorindex < 0)
164 bmp.SetPixel(x, map.Height - y - 1, Color.Red);
165 else
166 bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
167 }
168 }
169 return bmp;
170 }
171 }
172} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs
new file mode 100644
index 0000000..39ade10
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using System.Drawing.Imaging;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
34{
35 public class JPEG : ITerrainLoader
36 {
37 #region ITerrainLoader Members
38
39 public string FileExtension
40 {
41 get { return ".jpg"; }
42 }
43
44 public ITerrainChannel LoadFile(string filename)
45 {
46 throw new NotImplementedException();
47 }
48
49 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
50 {
51 throw new NotImplementedException();
52 }
53
54 public void SaveFile(string filename, ITerrainChannel map)
55 {
56 Bitmap colours = CreateBitmapFromMap(map);
57
58 colours.Save(filename, ImageFormat.Jpeg);
59 }
60
61 #endregion
62
63 public override string ToString()
64 {
65 return "JPEG";
66 }
67
68 private Bitmap CreateBitmapFromMap(ITerrainChannel map)
69 {
70 Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
71
72 int pallete = gradientmapLd.Height;
73
74 Bitmap bmp = new Bitmap(map.Width, map.Height);
75 Color[] colours = new Color[pallete];
76
77 for (int i = 0; i < pallete; i++)
78 {
79 colours[i] = gradientmapLd.GetPixel(0, i);
80 }
81
82 for (int y = 0; y < map.Height; y++)
83 {
84 for (int x = 0; x < map.Width; x++)
85 {
86 // 512 is the largest possible height before colours clamp
87 int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
88 bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
89 }
90 }
91 return bmp;
92 }
93 }
94} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs
new file mode 100644
index 0000000..468ecc9
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs
@@ -0,0 +1,148 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using OpenSim.Region.Environment.Interfaces;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
33{
34 public class LLRAW : ITerrainLoader
35 {
36 #region ITerrainLoader Members
37
38 public ITerrainChannel LoadFile(string filename)
39 {
40 TerrainChannel retval = new TerrainChannel();
41
42 FileInfo file = new FileInfo(filename);
43 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
44 BinaryReader bs = new BinaryReader(s);
45 int x, y;
46 for (y = 0; y < retval.Height; y++)
47 {
48 for (x = 0; x < retval.Width; x++)
49 {
50 retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0);
51 bs.ReadBytes(11); // Advance the stream to next bytes.
52 }
53 }
54
55 bs.Close();
56 s.Close();
57
58 return retval;
59 }
60
61 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
62 {
63 throw new NotImplementedException();
64 }
65
66 public void SaveFile(string filename, ITerrainChannel map)
67 {
68 FileInfo file = new FileInfo(filename);
69 FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
70 BinaryWriter binStream = new BinaryWriter(s);
71
72 // Generate a smegging big lookup table to speed the operation up (it needs it)
73 double[] lookupHeightTable = new double[65536];
74 int i, j, x, y;
75 for (i = 0; i < 256; i++)
76 {
77 for (j = 0; j < 256; j++)
78 {
79 lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0));
80 }
81 }
82
83 // Output the calculated raw
84 for (y = 0; y < map.Height; y++)
85 {
86 for (x = 0; x < map.Width; x++)
87 {
88 double t = map[x, y];
89 double min = double.MaxValue;
90 int index = 0;
91
92 for (i = 0; i < 65536; i++)
93 {
94 if (Math.Abs(t - lookupHeightTable[i]) < min)
95 {
96 min = Math.Abs(t - lookupHeightTable[i]);
97 index = i;
98 }
99 }
100
101 byte red = (byte) (index & 0xFF);
102 byte green = (byte) ((index >> 8) & 0xFF);
103 byte blue = 20;
104 byte alpha1 = 0; // Land Parcels
105 byte alpha2 = 0; // For Sale Land
106 byte alpha3 = 0; // Public Edit Object
107 byte alpha4 = 0; // Public Edit Land
108 byte alpha5 = 255; // Safe Land
109 byte alpha6 = 255; // Flying Allowed
110 byte alpha7 = 255; // Create Landmark
111 byte alpha8 = 255; // Outside Scripts
112 byte alpha9 = red;
113 byte alpha10 = green;
114
115 binStream.Write(red);
116 binStream.Write(green);
117 binStream.Write(blue);
118 binStream.Write(alpha1);
119 binStream.Write(alpha2);
120 binStream.Write(alpha3);
121 binStream.Write(alpha4);
122 binStream.Write(alpha5);
123 binStream.Write(alpha6);
124 binStream.Write(alpha7);
125 binStream.Write(alpha8);
126 binStream.Write(alpha9);
127 binStream.Write(alpha10);
128 }
129 }
130
131 binStream.Close();
132 s.Close();
133 }
134
135
136 public string FileExtension
137 {
138 get { return ".raw"; }
139 }
140
141 #endregion
142
143 public override string ToString()
144 {
145 return "LL/SL RAW";
146 }
147 }
148} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs
new file mode 100644
index 0000000..07072be
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
33{
34 internal class PNG : GenericSystemDrawing
35 {
36 public override void SaveFile(string filename, ITerrainChannel map)
37 {
38 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
39
40 colours.Save(filename, ImageFormat.Png);
41 }
42
43 public override string ToString()
44 {
45 return "PNG";
46 }
47 }
48} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs
new file mode 100644
index 0000000..71f56c5
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs
@@ -0,0 +1,153 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
32{
33 public class RAW32 : ITerrainLoader
34 {
35 #region ITerrainLoader Members
36
37 public string FileExtension
38 {
39 get { return ".r32"; }
40 }
41
42 public ITerrainChannel LoadFile(string filename)
43 {
44 TerrainChannel retval = new TerrainChannel();
45
46 FileInfo file = new FileInfo(filename);
47 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
48 BinaryReader bs = new BinaryReader(s);
49 int x, y;
50 for (y = 0; y < retval.Height; y++)
51 {
52 for (x = 0; x < retval.Width; x++)
53 {
54 retval[x, y] = bs.ReadSingle();
55 }
56 }
57
58 bs.Close();
59 s.Close();
60
61 return retval;
62 }
63
64 public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
65 {
66 TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
67
68 FileInfo file = new FileInfo(filename);
69 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
70 BinaryReader bs = new BinaryReader(s);
71
72 int currFileXOffset = 0;
73 int currFileYOffset = 0;
74
75 // if our region isn't on the first Y section of the areas to be landscaped, then
76 // advance to our section of the file
77 while (currFileYOffset < offsetY)
78 {
79 // read a whole strip of regions
80 int heightsToRead = sectionHeight * (fileWidth * sectionWidth);
81 bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file
82 currFileYOffset++;
83 }
84
85 // got to the Y start offset within the file of our region
86 // so read the file bits associated with our region
87 int x, y;
88 // for each Y within our Y offset
89 for (y = 0; y < sectionHeight; y++)
90 {
91 currFileXOffset = 0;
92
93 // if our region isn't the first X section of the areas to be landscaped, then
94 // advance the stream to the X start pos of our section in the file
95 // i.e. eat X upto where we start
96 while (currFileXOffset < offsetX)
97 {
98 bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
99 currFileXOffset++;
100 }
101
102 // got to our X offset, so write our regions X line
103 for (x = 0; x < sectionWidth; x++)
104 {
105 // Read a strip and continue
106 retval[x, y] = bs.ReadSingle();
107 }
108 // record that we wrote it
109 currFileXOffset++;
110
111 // if our region isn't the last X section of the areas to be landscaped, then
112 // advance the stream to the end of this Y column
113 while (currFileXOffset < fileWidth)
114 {
115 // eat the next regions x line
116 bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
117 currFileXOffset++;
118 }
119 }
120
121 bs.Close();
122 s.Close();
123
124 return retval;
125 }
126
127 public void SaveFile(string filename, ITerrainChannel map)
128 {
129 FileInfo file = new FileInfo(filename);
130 FileStream s = file.Open(FileMode.Create, FileAccess.Write);
131 BinaryWriter bs = new BinaryWriter(s);
132
133 int x, y;
134 for (y = 0; y < map.Height; y++)
135 {
136 for (x = 0; x < map.Width; x++)
137 {
138 bs.Write((float) map[x, y]);
139 }
140 }
141
142 bs.Close();
143 s.Close();
144 }
145
146 #endregion
147
148 public override string ToString()
149 {
150 return "RAW32";
151 }
152 }
153} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs
new file mode 100644
index 0000000..d206763
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
33{
34 internal class TIFF : GenericSystemDrawing
35 {
36 public override void SaveFile(string filename, ITerrainChannel map)
37 {
38 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
39
40 colours.Save(filename, ImageFormat.Tiff);
41 }
42
43 public override string ToString()
44 {
45 return "TIFF";
46 }
47 }
48} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs
new file mode 100644
index 0000000..f2672ad
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs
@@ -0,0 +1,127 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Text;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
34{
35 /// <summary>
36 /// Terragen File Format Loader
37 /// Built from specification at
38 /// http://www.planetside.co.uk/terragen/dev/tgterrain.html
39 /// </summary>
40 internal class Terragen : ITerrainLoader
41 {
42 #region ITerrainLoader Members
43
44 public ITerrainChannel LoadFile(string filename)
45 {
46 TerrainChannel retval = new TerrainChannel();
47
48 FileInfo file = new FileInfo(filename);
49 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
50 BinaryReader bs = new BinaryReader(s);
51
52 bool eof = false;
53 if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
54 {
55 // Terragen file
56 while (eof == false)
57 {
58 int w = 256;
59 int h = 256;
60 string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4));
61 switch (tmp)
62 {
63 case "SIZE":
64 int sztmp = bs.ReadInt16() + 1;
65 w = sztmp;
66 h = sztmp;
67 bs.ReadInt16();
68 break;
69 case "XPTS":
70 w = bs.ReadInt16();
71 bs.ReadInt16();
72 break;
73 case "YPTS":
74 h = bs.ReadInt16();
75 bs.ReadInt16();
76 break;
77 case "ALTW":
78 eof = true;
79 Int16 heightScale = bs.ReadInt16();
80 Int16 baseHeight = bs.ReadInt16();
81 retval = new TerrainChannel(w, h);
82 int x, y;
83 for (x = 0; x < w; x++)
84 {
85 for (y = 0; y < h; y++)
86 {
87 retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0;
88 }
89 }
90 break;
91 default:
92 bs.ReadInt32();
93 break;
94 }
95 }
96 }
97
98 bs.Close();
99 s.Close();
100
101 return retval;
102 }
103
104 public void SaveFile(string filename, ITerrainChannel map)
105 {
106 char[] header = "TERRAGENTERRAIN".ToCharArray();
107 throw new NotImplementedException();
108 }
109
110 public string FileExtension
111 {
112 get { return ".ter"; }
113 }
114
115 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
116 {
117 throw new NotImplementedException();
118 }
119
120 #endregion
121
122 public override string ToString()
123 {
124 return "Terragen";
125 }
126 }
127} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs
new file mode 100644
index 0000000..7bf81d3
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
31{
32 public class FlattenArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 double sum = 0.0;
39 double steps = 0.0;
40 double avg;
41
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 for (y = 0; y < map.Height; y++)
46 {
47 if (fillArea[x, y])
48 {
49 sum += map[x, y];
50 steps += 1.0;
51 }
52 }
53 }
54
55 avg = sum / steps;
56
57 double str = 0.1 * strength; // == 0.2 in the default client
58
59 for (x = 0; x < map.Width; x++)
60 {
61 for (y = 0; y < map.Height; y++)
62 {
63 if (fillArea[x, y])
64 map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
65 }
66 }
67 }
68
69 #endregion
70 }
71} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs
new file mode 100644
index 0000000..a7a4431
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
31{
32 public class LowerArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 int x;
39 for (x = 0; x < map.Width; x++)
40 {
41 int y;
42 for (y = 0; y < map.Height; y++)
43 {
44 if (fillArea[x, y])
45 {
46 map[x, y] -= strength;
47 }
48 }
49 }
50 }
51
52 #endregion
53 }
54} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs
new file mode 100644
index 0000000..3da3826
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
32{
33 public class NoiseArea : ITerrainFloodEffect
34 {
35 #region ITerrainFloodEffect Members
36
37 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
38 {
39 int x, y;
40 for (x = 0; x < map.Width; x++)
41 {
42 for (y = 0; y < map.Height; y++)
43 {
44 if (fillArea[x, y])
45 {
46 double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
47
48 map[x, y] += noise * strength;
49 }
50 }
51 }
52 }
53
54 #endregion
55 }
56} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs
new file mode 100644
index 0000000..b57caed
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
31{
32 public class RaiseArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 int x, y;
39 for (x = 0; x < map.Width; x++)
40 {
41 for (y = 0; y < map.Height; y++)
42 {
43 if (fillArea[x, y])
44 {
45 map[x, y] += strength;
46 }
47 }
48 }
49 }
50
51 #endregion
52 }
53} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs
new file mode 100644
index 0000000..76a2cae
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
31{
32 public class RevertArea : ITerrainFloodEffect
33 {
34 private readonly ITerrainChannel m_revertmap;
35
36 public RevertArea(ITerrainChannel revertmap)
37 {
38 m_revertmap = revertmap;
39 }
40
41 #region ITerrainFloodEffect Members
42
43 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
44 {
45 int x, y;
46 for (x = 0; x < map.Width; x++)
47 {
48 for (y = 0; y < map.Height; y++)
49 {
50 if (fillArea[x, y])
51 {
52 map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
53 }
54 }
55 }
56 }
57
58 #endregion
59 }
60} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs
new file mode 100644
index 0000000..bdd9f18
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs
@@ -0,0 +1,114 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
31{
32 public class SmoothArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 double area = strength;
39 double step = strength / 4.0;
40
41 double[,] manipulate = new double[map.Width,map.Height];
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 for (y = 0; y < map.Height; y++)
46 {
47 if (!fillArea[x, y])
48 continue;
49
50 double average = 0.0;
51 int avgsteps = 0;
52
53 double n;
54 for (n = 0.0 - area; n < area; n += step)
55 {
56 double l;
57 for (l = 0.0 - area; l < area; l += step)
58 {
59 avgsteps++;
60 average += GetBilinearInterpolate(x + n, y + l, map);
61 }
62 }
63
64 manipulate[x, y] = average / avgsteps;
65 }
66 }
67 for (x = 0; x < map.Width; x++)
68 {
69 for (y = 0; y < map.Height; y++)
70 {
71 if (!fillArea[x, y])
72 continue;
73
74 map[x, y] = manipulate[x, y];
75 }
76 }
77 }
78
79 #endregion
80
81 private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
82 {
83 int w = map.Width;
84 int h = map.Height;
85
86 if (x > w - 2.0)
87 x = w - 2.0;
88 if (y > h - 2.0)
89 y = h - 2.0;
90 if (x < 0.0)
91 x = 0.0;
92 if (y < 0.0)
93 y = 0.0;
94
95 int stepSize = 1;
96 double h00 = map[(int) x, (int) y];
97 double h10 = map[(int) x + stepSize, (int) y];
98 double h01 = map[(int) x, (int) y + stepSize];
99 double h11 = map[(int) x + stepSize, (int) y + stepSize];
100 double h1 = h00;
101 double h2 = h10;
102 double h3 = h01;
103 double h4 = h11;
104 double a00 = h1;
105 double a10 = h2 - h1;
106 double a01 = h3 - h1;
107 double a11 = h1 - h2 - h3 + h4;
108 double partialx = x - (int) x;
109 double partialz = y - (int) y;
110 double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
111 return hi;
112 }
113 }
114} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs
new file mode 100644
index 0000000..821fc4b
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain
31{
32 public interface ITerrainEffect
33 {
34 void RunEffect(ITerrainChannel map);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs
new file mode 100644
index 0000000..6b0d7f9
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain
32{
33 public interface ITerrainFloodEffect
34 {
35 void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength);
36 }
37} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs
new file mode 100644
index 0000000..6211892
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain
31{
32 public interface ITerrainLoader
33 {
34 string FileExtension { get; }
35 ITerrainChannel LoadFile(string filename);
36 ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
37 void SaveFile(string filename, ITerrainChannel map);
38 }
39} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs
new file mode 100644
index 0000000..756354a
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs
@@ -0,0 +1,8 @@
1namespace OpenSim.Region.Environment.Modules.World.Terrain
2{
3 public interface ITerrainModule
4 {
5 void LoadFromFile(string filename);
6 void SaveToFile(string filename);
7 }
8} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs
new file mode 100644
index 0000000..d73f44d
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain
31{
32 public interface ITerrainPaintableEffect
33 {
34 void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs
new file mode 100644
index 0000000..dbaec0f
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using Nini.Config;
31using OpenJPEGNet;
32using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Scenes;
34
35namespace OpenSim.Region.Environment.Modules.World.Terrain
36{
37 internal class MapImageModule : IMapImageGenerator, IRegionModule
38 {
39 private Scene m_scene;
40
41 #region IMapImageGenerator Members
42
43 public byte[] WriteJpeg2000Image(string gradientmap)
44 {
45 byte[] imageData = null;
46
47 Bitmap bmp = TerrainToBitmap(gradientmap);
48
49 try
50 {
51 imageData = OpenJPEG.EncodeFromImage(bmp, true);
52 }
53 catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
54 {
55 Console.WriteLine("Failed generating terrain map: " + e);
56 }
57
58 return imageData;
59 }
60
61 #endregion
62
63 #region IRegionModule Members
64
65 public void Initialise(Scene scene, IConfigSource source)
66 {
67 m_scene = scene;
68 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
69 }
70
71 public void PostInitialise()
72 {
73 }
74
75 public void Close()
76 {
77 }
78
79 public string Name
80 {
81 get { return "MapImageModule"; }
82 }
83
84 public bool IsSharedModule
85 {
86 get { return false; }
87 }
88
89 #endregion
90
91 private void ShadeBuildings(ref Bitmap map)
92 {
93 lock (map)
94 {
95 lock (m_scene.Entities)
96 {
97 foreach (EntityBase entity in m_scene.Entities.Values)
98 {
99 if (entity is SceneObjectGroup)
100 {
101 SceneObjectGroup sog = (SceneObjectGroup) entity;
102
103 foreach (SceneObjectPart primitive in sog.Children.Values)
104 {
105 int x, y, w, h;
106 x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
107 y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
108 w = (int) primitive.Scale.X;
109 h = (int) primitive.Scale.Y;
110
111 int dx;
112 for (dx = x; dx < x + w; dx++)
113 {
114 int dy;
115 for (dy = y; dy < y + h; dy++)
116 {
117 if (x < 0 || y < 0)
118 continue;
119 if (x >= map.Width || y >= map.Height)
120 continue;
121
122 map.SetPixel(dx, dy, Color.DarkGray);
123 }
124 }
125 }
126 }
127 }
128 }
129 }
130 }
131
132 private Bitmap TerrainToBitmap(string gradientmap)
133 {
134 Bitmap gradientmapLd = new Bitmap(gradientmap);
135
136 int pallete = gradientmapLd.Height;
137
138 Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
139 Color[] colours = new Color[pallete];
140
141 for (int i = 0; i < pallete; i++)
142 {
143 colours[i] = gradientmapLd.GetPixel(0, i);
144 }
145
146 lock (m_scene.Heightmap)
147 {
148 ITerrainChannel copy = m_scene.Heightmap;
149 for (int y = 0; y < copy.Height; y++)
150 {
151 for (int x = 0; x < copy.Width; x++)
152 {
153 // 512 is the largest possible height before colours clamp
154 int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1));
155
156 // Handle error conditions
157 if (colorindex > pallete - 1 || colorindex < 0)
158 bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
159 else
160 bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
161 }
162 }
163 ShadeBuildings(ref bmp);
164 return bmp;
165 }
166 }
167 }
168} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs
new file mode 100644
index 0000000..29448aa
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs
@@ -0,0 +1,312 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
32{
33 /// <summary>
34 /// Hydraulic Erosion Brush
35 /// </summary>
36 public class ErodeSphere : ITerrainPaintableEffect
37 {
38 private double rainHeight = 0.2;
39 private int rounds = 10;
40 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
41 private double waterSaturation = 0.30; // Can carry 1% of water in height
42
43 #region Supporting Functions
44
45 private int[] Neighbours(NeighbourSystem type, int index)
46 {
47 int[] coord = new int[2];
48
49 index++;
50
51 switch (type)
52 {
53 case NeighbourSystem.Moore:
54 switch (index)
55 {
56 case 1:
57 coord[0] = -1;
58 coord[1] = -1;
59 break;
60
61 case 2:
62 coord[0] = -0;
63 coord[1] = -1;
64 break;
65
66 case 3:
67 coord[0] = +1;
68 coord[1] = -1;
69 break;
70
71 case 4:
72 coord[0] = -1;
73 coord[1] = -0;
74 break;
75
76 case 5:
77 coord[0] = -0;
78 coord[1] = -0;
79 break;
80
81 case 6:
82 coord[0] = +1;
83 coord[1] = -0;
84 break;
85
86 case 7:
87 coord[0] = -1;
88 coord[1] = +1;
89 break;
90
91 case 8:
92 coord[0] = -0;
93 coord[1] = +1;
94 break;
95
96 case 9:
97 coord[0] = +1;
98 coord[1] = +1;
99 break;
100
101 default:
102 break;
103 }
104 break;
105
106 case NeighbourSystem.VonNeumann:
107 switch (index)
108 {
109 case 1:
110 coord[0] = 0;
111 coord[1] = -1;
112 break;
113
114 case 2:
115 coord[0] = -1;
116 coord[1] = 0;
117 break;
118
119 case 3:
120 coord[0] = +1;
121 coord[1] = 0;
122 break;
123
124 case 4:
125 coord[0] = 0;
126 coord[1] = +1;
127 break;
128
129 case 5:
130 coord[0] = -0;
131 coord[1] = -0;
132 break;
133
134 default:
135 break;
136 }
137 break;
138 }
139
140 return coord;
141 }
142
143 private enum NeighbourSystem
144 {
145 Moore,
146 VonNeumann
147 } ;
148
149 #endregion
150
151 #region ITerrainPaintableEffect Members
152
153 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
154 {
155 strength = TerrainUtil.MetersToSphericalStrength(strength);
156
157 int x, y;
158 // Using one 'rain' round for this, so skipping a useless loop
159 // Will need to adapt back in for the Flood brush
160
161 ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
162 ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
163
164 // Fill with rain
165 for (x = 0; x < water.Width; x++)
166 for (y = 0; y < water.Height; y++)
167 water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
168
169 for (int i = 0; i < rounds; i++)
170 {
171 // Erode underlying terrain
172 for (x = 0; x < water.Width; x++)
173 {
174 for (y = 0; y < water.Height; y++)
175 {
176 double solConst = (1.0 / rounds);
177 double sedDelta = water[x, y] * solConst;
178 map[x, y] -= sedDelta;
179 sediment[x, y] += sedDelta;
180 }
181 }
182
183 // Move water
184 for (x = 0; x < water.Width; x++)
185 {
186 for (y = 0; y < water.Height; y++)
187 {
188 if (water[x, y] <= 0)
189 continue;
190
191 // Step 1. Calculate average of neighbours
192
193 int neighbours = 0;
194 double altitudeTotal = 0.0;
195 double altitudeMe = map[x, y] + water[x, y];
196
197 int NEIGHBOUR_ME = 4;
198
199 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
200
201 for (int j = 0; j < NEIGHBOUR_MAX; j++)
202 {
203 if (j != NEIGHBOUR_ME)
204 {
205 int[] coords = Neighbours(type, j);
206
207 coords[0] += x;
208 coords[1] += y;
209
210 if (coords[0] > map.Width - 1)
211 continue;
212 if (coords[1] > map.Height - 1)
213 continue;
214 if (coords[0] < 0)
215 continue;
216 if (coords[1] < 0)
217 continue;
218
219 // Calculate total height of this neighbour
220 double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
221
222 // If it's greater than me...
223 if (altitudeNeighbour - altitudeMe < 0)
224 {
225 // Add it to our calculations
226 neighbours++;
227 altitudeTotal += altitudeNeighbour;
228 }
229 }
230 }
231
232 if (neighbours == 0)
233 continue;
234
235 double altitudeAvg = altitudeTotal / neighbours;
236
237 // Step 2. Allocate water to neighbours.
238 for (int j = 0; j < NEIGHBOUR_MAX; j++)
239 {
240 if (j != NEIGHBOUR_ME)
241 {
242 int[] coords = Neighbours(type, j);
243
244 coords[0] += x;
245 coords[1] += y;
246
247 if (coords[0] > map.Width - 1)
248 continue;
249 if (coords[1] > map.Height - 1)
250 continue;
251 if (coords[0] < 0)
252 continue;
253 if (coords[1] < 0)
254 continue;
255
256 // Skip if we dont have water to begin with.
257 if (water[x, y] < 0)
258 continue;
259
260 // Calculate our delta average
261 double altitudeDelta = altitudeMe - altitudeAvg;
262
263 if (altitudeDelta < 0)
264 continue;
265
266 // Calculate how much water we can move
267 double waterMin = Math.Min(water[x, y], altitudeDelta);
268 double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
269 / altitudeTotal);
270
271 double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
272
273 if (sedimentDelta > 0)
274 {
275 sediment[x, y] -= sedimentDelta;
276 sediment[coords[0], coords[1]] += sedimentDelta;
277 }
278 }
279 }
280 }
281 }
282
283 // Evaporate
284
285 for (x = 0; x < water.Width; x++)
286 {
287 for (y = 0; y < water.Height; y++)
288 {
289 water[x, y] *= 1.0 - (rainHeight / rounds);
290
291 double waterCapacity = waterSaturation * water[x, y];
292
293 double sedimentDeposit = sediment[x, y] - waterCapacity;
294 if (sedimentDeposit > 0)
295 {
296 sediment[x, y] -= sedimentDeposit;
297 map[x, y] += sedimentDeposit;
298 }
299 }
300 }
301 }
302
303 // Deposit any remainder (should be minimal)
304 for (x = 0; x < water.Width; x++)
305 for (y = 0; y < water.Height; y++)
306 if (sediment[x, y] > 0)
307 map[x, y] += sediment[x, y];
308 }
309
310 #endregion
311 }
312} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs
new file mode 100644
index 0000000..6a5a166
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs
@@ -0,0 +1,127 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
31{
32 public class FlattenSphere : ITerrainPaintableEffect
33 {
34// TODO: unused
35// private double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
36// {
37// int w = map.Width;
38// int h = map.Height;
39
40// if (x > w - 2.0)
41// x = w - 2.0;
42// if (y > h - 2.0)
43// y = h - 2.0;
44// if (x < 0.0)
45// x = 0.0;
46// if (y < 0.0)
47// y = 0.0;
48
49// int stepSize = 1;
50// double h00 = map[(int)x, (int)y];
51// double h10 = map[(int)x + stepSize, (int)y];
52// double h01 = map[(int)x, (int)y + stepSize];
53// double h11 = map[(int)x + stepSize, (int)y + stepSize];
54// double h1 = h00;
55// double h2 = h10;
56// double h3 = h01;
57// double h4 = h11;
58// double a00 = h1;
59// double a10 = h2 - h1;
60// double a01 = h3 - h1;
61// double a11 = h1 - h2 - h3 + h4;
62// double partialx = x - (int)x;
63// double partialz = y - (int)y;
64// double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
65// return hi;
66// }
67
68 #region ITerrainPaintableEffect Members
69
70 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
71 {
72 strength = TerrainUtil.MetersToSphericalStrength(strength);
73
74 int x, y;
75 double[,] tweak = new double[map.Width,map.Height];
76
77 double area = strength;
78 double step = strength / 4.0;
79
80 double sum = 0.0;
81 double step2 = 0.0;
82 double avg = 0.0;
83
84 // compute delta map
85 for (x = 0; x < map.Width; x++)
86 {
87 for (y = 0; y < map.Height; y++)
88 {
89 double z = SphericalFactor(x, y, rx, ry, strength);
90
91 if (z > 0) // add in non-zero amount
92 {
93 sum += map[x, y] * z;
94 step2 += z;
95 }
96 }
97 }
98
99 avg = sum / step2;
100
101 // blend in map
102 for (x = 0; x < map.Width; x++)
103 {
104 for (y = 0; y < map.Height; y++)
105 {
106 double z = SphericalFactor(x, y, rx, ry, strength) * duration;
107
108 if (z > 0) // add in non-zero amount
109 {
110 if (z > 1.0)
111 z = 1.0;
112
113 map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z);
114 }
115 }
116 }
117 }
118
119 #endregion
120
121 private double SphericalFactor(double x, double y, double rx, double ry, double size)
122 {
123 double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
124 return z;
125 }
126 }
127} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs
new file mode 100644
index 0000000..0b80407
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
32{
33 public class LowerSphere : ITerrainPaintableEffect
34 {
35 #region ITerrainPaintableEffect Members
36
37 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
38 {
39 strength = TerrainUtil.MetersToSphericalStrength(strength);
40
41 int x, y;
42 for (x = 0; x < map.Width; x++)
43 {
44 // Skip everything unlikely to be affected
45 if (Math.Abs(x - rx) > strength * 1.1)
46 continue;
47
48 for (y = 0; y < map.Height; y++)
49 {
50 // Skip everything unlikely to be affected
51 if (Math.Abs(y - ry) > strength * 1.1)
52 continue;
53
54 // Calculate a sphere and add it to the heighmap
55 double z = strength;
56 z *= z;
57 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
58
59 if (z > 0.0)
60 map[x, y] -= z * duration;
61 }
62 }
63 }
64
65 #endregion
66 }
67} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs
new file mode 100644
index 0000000..a188e9f
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Framework;
30using OpenSim.Region.Environment.Interfaces;
31
32namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
33{
34 public class NoiseSphere : ITerrainPaintableEffect
35 {
36 #region ITerrainPaintableEffect Members
37
38 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
39 {
40 strength = TerrainUtil.MetersToSphericalStrength(strength);
41
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 // Skip everything unlikely to be affected
46 if (Math.Abs(x - rx) > strength * 1.1)
47 continue;
48
49 for (y = 0; y < map.Height; y++)
50 {
51 // Skip everything unlikely to be affected
52 if (Math.Abs(y - ry) > strength * 1.1)
53 continue;
54
55 // Calculate a sphere and add it to the heighmap
56 double z = strength;
57 z *= z;
58 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
59
60 double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
61
62 if (z > 0.0)
63 map[x, y] += noise * z * duration;
64 }
65 }
66 }
67
68 #endregion
69 }
70} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs
new file mode 100644
index 0000000..dc56cf1
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
32{
33 /// <summary>
34 /// Speed-Optimised Hybrid Erosion Brush
35 ///
36 /// As per Jacob Olsen's Paper
37 /// http://www.oddlabs.com/download/terrain_generation.pdf
38 /// </summary>
39 public class OlsenSphere : ITerrainPaintableEffect
40 {
41 private double nConst = 1024.0;
42 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
43
44 #region Supporting Functions
45
46 private int[] Neighbours(NeighbourSystem type, int index)
47 {
48 int[] coord = new int[2];
49
50 index++;
51
52 switch (type)
53 {
54 case NeighbourSystem.Moore:
55 switch (index)
56 {
57 case 1:
58 coord[0] = -1;
59 coord[1] = -1;
60 break;
61
62 case 2:
63 coord[0] = -0;
64 coord[1] = -1;
65 break;
66
67 case 3:
68 coord[0] = +1;
69 coord[1] = -1;
70 break;
71
72 case 4:
73 coord[0] = -1;
74 coord[1] = -0;
75 break;
76
77 case 5:
78 coord[0] = -0;
79 coord[1] = -0;
80 break;
81
82 case 6:
83 coord[0] = +1;
84 coord[1] = -0;
85 break;
86
87 case 7:
88 coord[0] = -1;
89 coord[1] = +1;
90 break;
91
92 case 8:
93 coord[0] = -0;
94 coord[1] = +1;
95 break;
96
97 case 9:
98 coord[0] = +1;
99 coord[1] = +1;
100 break;
101
102 default:
103 break;
104 }
105 break;
106
107 case NeighbourSystem.VonNeumann:
108 switch (index)
109 {
110 case 1:
111 coord[0] = 0;
112 coord[1] = -1;
113 break;
114
115 case 2:
116 coord[0] = -1;
117 coord[1] = 0;
118 break;
119
120 case 3:
121 coord[0] = +1;
122 coord[1] = 0;
123 break;
124
125 case 4:
126 coord[0] = 0;
127 coord[1] = +1;
128 break;
129
130 case 5:
131 coord[0] = -0;
132 coord[1] = -0;
133 break;
134
135 default:
136 break;
137 }
138 break;
139 }
140
141 return coord;
142 }
143
144 private double SphericalFactor(double x, double y, double rx, double ry, double size)
145 {
146 double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
147 return z;
148 }
149
150 private enum NeighbourSystem
151 {
152 Moore,
153 VonNeumann
154 } ;
155
156 #endregion
157
158 #region ITerrainPaintableEffect Members
159
160 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
161 {
162 strength = TerrainUtil.MetersToSphericalStrength(strength);
163
164 int x, y;
165
166 for (x = 0; x < map.Width; x++)
167 {
168 for (y = 0; y < map.Height; y++)
169 {
170 double z = SphericalFactor(x, y, rx, ry, strength);
171
172 if (z > 0) // add in non-zero amount
173 {
174 int NEIGHBOUR_ME = 4;
175 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
176
177 double max = Double.MinValue;
178 int loc = 0;
179 double cellmax = 0;
180
181
182 for (int j = 0; j < NEIGHBOUR_MAX; j++)
183 {
184 if (j != NEIGHBOUR_ME)
185 {
186 int[] coords = Neighbours(type, j);
187
188 coords[0] += x;
189 coords[1] += y;
190
191 if (coords[0] > map.Width - 1)
192 continue;
193 if (coords[1] > map.Height - 1)
194 continue;
195 if (coords[0] < 0)
196 continue;
197 if (coords[1] < 0)
198 continue;
199
200 cellmax = map[x, y] - map[coords[0], coords[1]];
201 if (cellmax > max)
202 {
203 max = cellmax;
204 loc = j;
205 }
206 }
207 }
208
209 double T = nConst / ((map.Width + map.Height) / 2);
210 // Apply results
211 if (0 < max && max <= T)
212 {
213 int[] maxCoords = Neighbours(type, loc);
214 double heightDelta = 0.5 * max * z * duration;
215 map[x, y] -= heightDelta;
216 map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
217 }
218 }
219 }
220 }
221 }
222
223 #endregion
224 }
225} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs
new file mode 100644
index 0000000..cd5a22b
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
32{
33 public class RaiseSphere : ITerrainPaintableEffect
34 {
35 #region ITerrainPaintableEffect Members
36
37 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
38 {
39 strength = TerrainUtil.MetersToSphericalStrength(strength);
40
41 int x, y;
42 for (x = 0; x < map.Width; x++)
43 {
44 // Skip everything unlikely to be affected
45 if (Math.Abs(x - rx) > strength * 1.1)
46 continue;
47
48 for (y = 0; y < map.Height; y++)
49 {
50 // Skip everything unlikely to be affected
51 if (Math.Abs(y - ry) > strength * 1.1)
52 continue;
53
54 // Calculate a sphere and add it to the heighmap
55 double z = strength;
56 z *= z;
57 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
58
59 if (z > 0.0)
60 map[x, y] += z * duration;
61 }
62 }
63 }
64
65 #endregion
66 }
67} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs
new file mode 100644
index 0000000..5b92cb5
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
32{
33 public class RevertSphere : ITerrainPaintableEffect
34 {
35 private ITerrainChannel m_revertmap;
36
37 public RevertSphere(ITerrainChannel revertmap)
38 {
39 m_revertmap = revertmap;
40 }
41
42 #region ITerrainPaintableEffect Members
43
44 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
45 {
46 strength = TerrainUtil.MetersToSphericalStrength(strength);
47
48 if (duration > 1.0)
49 duration = 1.0;
50 if (duration < 0)
51 return;
52
53 int x, y;
54 for (x = 0; x < map.Width; x++)
55 {
56 // Skip everything unlikely to be affected
57 if (Math.Abs(x - rx) > strength * 1.1)
58 continue;
59
60 for (y = 0; y < map.Height; y++)
61 {
62 // Skip everything unlikely to be affected
63 if (Math.Abs(y - ry) > strength * 1.1)
64 continue;
65
66 // Calculate a sphere and add it to the heighmap
67 double z = strength;
68 z *= z;
69 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
70
71 if (z > 0.0)
72 {
73 z *= duration;
74 map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
75 }
76 }
77 }
78 }
79
80 #endregion
81 }
82} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs
new file mode 100644
index 0000000..305a875
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs
@@ -0,0 +1,93 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
31{
32 public class SmoothSphere : ITerrainPaintableEffect
33 {
34 #region ITerrainPaintableEffect Members
35
36 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
37 {
38 strength = TerrainUtil.MetersToSphericalStrength(strength);
39
40 int x, y;
41 double[,] tweak = new double[map.Width,map.Height];
42
43 double n, l;
44 double area = strength;
45 double step = strength / 4.0;
46
47 // compute delta map
48 for (x = 0; x < map.Width; x++)
49 {
50 for (y = 0; y < map.Height; y++)
51 {
52 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
53
54 if (z > 0) // add in non-zero amount
55 {
56 double average = 0.0;
57 int avgsteps = 0;
58
59 for (n = 0.0 - area; n < area; n += step)
60 {
61 for (l = 0.0 - area; l < area; l += step)
62 {
63 avgsteps++;
64 average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
65 }
66 }
67 tweak[x, y] = average / avgsteps;
68 }
69 }
70 }
71 // blend in map
72 for (x = 0; x < map.Width; x++)
73 {
74 for (y = 0; y < map.Height; y++)
75 {
76 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
77
78 if (z > 0) // add in non-zero amount
79 {
80 double da = z;
81 double a = (map[x, y] - tweak[x, y]) * da;
82 double newz = map[x, y] - (a * duration);
83
84 if (newz > 0.0)
85 map[x, y] = newz;
86 }
87 }
88 }
89 }
90
91 #endregion
92 }
93} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs
new file mode 100644
index 0000000..2d81054
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs
@@ -0,0 +1,207 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
31{
32 /// <summary>
33 /// Thermal Weathering Paint Brush
34 /// </summary>
35 public class WeatherSphere : ITerrainPaintableEffect
36 {
37 private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
38 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
39
40 #region Supporting Functions
41
42 private int[] Neighbours(NeighbourSystem type, int index)
43 {
44 int[] coord = new int[2];
45
46 index++;
47
48 switch (type)
49 {
50 case NeighbourSystem.Moore:
51 switch (index)
52 {
53 case 1:
54 coord[0] = -1;
55 coord[1] = -1;
56 break;
57
58 case 2:
59 coord[0] = -0;
60 coord[1] = -1;
61 break;
62
63 case 3:
64 coord[0] = +1;
65 coord[1] = -1;
66 break;
67
68 case 4:
69 coord[0] = -1;
70 coord[1] = -0;
71 break;
72
73 case 5:
74 coord[0] = -0;
75 coord[1] = -0;
76 break;
77
78 case 6:
79 coord[0] = +1;
80 coord[1] = -0;
81 break;
82
83 case 7:
84 coord[0] = -1;
85 coord[1] = +1;
86 break;
87
88 case 8:
89 coord[0] = -0;
90 coord[1] = +1;
91 break;
92
93 case 9:
94 coord[0] = +1;
95 coord[1] = +1;
96 break;
97
98 default:
99 break;
100 }
101 break;
102
103 case NeighbourSystem.VonNeumann:
104 switch (index)
105 {
106 case 1:
107 coord[0] = 0;
108 coord[1] = -1;
109 break;
110
111 case 2:
112 coord[0] = -1;
113 coord[1] = 0;
114 break;
115
116 case 3:
117 coord[0] = +1;
118 coord[1] = 0;
119 break;
120
121 case 4:
122 coord[0] = 0;
123 coord[1] = +1;
124 break;
125
126 case 5:
127 coord[0] = -0;
128 coord[1] = -0;
129 break;
130
131 default:
132 break;
133 }
134 break;
135 }
136
137 return coord;
138 }
139
140 private enum NeighbourSystem
141 {
142 Moore,
143 VonNeumann
144 } ;
145
146 #endregion
147
148 #region ITerrainPaintableEffect Members
149
150 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
151 {
152 strength = TerrainUtil.MetersToSphericalStrength(strength);
153
154 int x, y;
155
156 for (x = 0; x < map.Width; x++)
157 {
158 for (y = 0; y < map.Height; y++)
159 {
160 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
161
162 if (z > 0) // add in non-zero amount
163 {
164 int NEIGHBOUR_ME = 4;
165
166 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
167
168 for (int j = 0; j < NEIGHBOUR_MAX; j++)
169 {
170 if (j != NEIGHBOUR_ME)
171 {
172 int[] coords = Neighbours(type, j);
173
174 coords[0] += x;
175 coords[1] += y;
176
177 if (coords[0] > map.Width - 1)
178 continue;
179 if (coords[1] > map.Height - 1)
180 continue;
181 if (coords[0] < 0)
182 continue;
183 if (coords[1] < 0)
184 continue;
185
186 double heightF = map[x, y];
187 double target = map[coords[0], coords[1]];
188
189 if (target > heightF + talus)
190 {
191 double calc = duration * ((target - heightF) - talus) * z;
192 heightF += calc;
193 target -= calc;
194 }
195
196 map[x, y] = heightF;
197 map[coords[0], coords[1]] = target;
198 }
199 }
200 }
201 }
202 }
203 }
204
205 #endregion
206 }
207} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs
new file mode 100644
index 0000000..e2df885
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs
@@ -0,0 +1,157 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain
32{
33 /// <summary>
34 /// A new version of the old Channel class, simplified
35 /// </summary>
36 public class TerrainChannel : ITerrainChannel
37 {
38 private readonly bool[,] taint;
39 private double[,] map;
40
41 public TerrainChannel()
42 {
43 map = new double[Constants.RegionSize,Constants.RegionSize];
44 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
45
46 int x;
47 for (x = 0; x < Constants.RegionSize; x++)
48 {
49 int y;
50 for (y = 0; y < Constants.RegionSize; y++)
51 {
52 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
53 double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
54 if (map[x, y] < spherFac)
55 {
56 map[x, y] = spherFac;
57 }
58 }
59 }
60 }
61
62 public TerrainChannel(double[,] import)
63 {
64 map = import;
65 taint = new bool[import.GetLength(0),import.GetLength(1)];
66 }
67
68 public TerrainChannel(bool createMap)
69 {
70 if (createMap)
71 {
72 map = new double[Constants.RegionSize,Constants.RegionSize];
73 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
74 }
75 }
76
77 public TerrainChannel(int w, int h)
78 {
79 map = new double[w,h];
80 taint = new bool[w / 16,h / 16];
81 }
82
83 #region ITerrainChannel Members
84
85 public int Width
86 {
87 get { return map.GetLength(0); }
88 }
89
90 public int Height
91 {
92 get { return map.GetLength(1); }
93 }
94
95 public ITerrainChannel MakeCopy()
96 {
97 TerrainChannel copy = new TerrainChannel(false);
98 copy.map = (double[,]) map.Clone();
99
100 return copy;
101 }
102
103 public float[] GetFloatsSerialised()
104 {
105 float[] heights = new float[Width * Height];
106 int i;
107
108 for (i = 0; i < Width * Height; i++)
109 {
110 heights[i] = (float) map[i % Width, i / Width];
111 }
112
113 return heights;
114 }
115
116 public double[,] GetDoubles()
117 {
118 return map;
119 }
120
121 public double this[int x, int y]
122 {
123 get { return map[x, y]; }
124 set
125 {
126 if (map[x, y] != value)
127 {
128 taint[x / 16, y / 16] = true;
129 map[x, y] = value;
130 }
131 }
132 }
133
134 public bool Tainted(int x, int y)
135 {
136 if (taint[x / 16, y / 16])
137 {
138 taint[x / 16, y / 16] = false;
139 return true;
140 }
141 else
142 {
143 return false;
144 }
145 }
146
147 #endregion
148
149 public TerrainChannel Copy()
150 {
151 TerrainChannel copy = new TerrainChannel(false);
152 copy.map = (double[,]) map.Clone();
153
154 return copy;
155 }
156 }
157} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs
new file mode 100644
index 0000000..1095cb9
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Environment.Modules.World.Terrain
31{
32 public class TerrainException : Exception
33 {
34 public TerrainException() : base()
35 {
36 }
37
38 public TerrainException(string msg) : base(msg)
39 {
40 }
41
42 public TerrainException(string msg, Exception e) : base(msg, e)
43 {
44 }
45 }
46} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
new file mode 100644
index 0000000..cf85aa4
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
@@ -0,0 +1,737 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using libsecondlife;
33using log4net;
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Modules.Framework;
38using OpenSim.Region.Environment.Modules.World.Terrain;
39using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
40using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
41using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
42using OpenSim.Region.Environment.Scenes;
43
44namespace OpenSim.Region.Environment.Modules.World.Terrain
45{
46 public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule
47 {
48 #region StandardTerrainEffects enum
49
50 /// <summary>
51 /// A standard set of terrain brushes and effects recognised by viewers
52 /// </summary>
53 public enum StandardTerrainEffects : byte
54 {
55 Flatten = 0,
56 Raise = 1,
57 Lower = 2,
58 Smooth = 3,
59 Noise = 4,
60 Revert = 5,
61
62 // Extended brushes
63 Erode = 255,
64 Weather = 254,
65 Olsen = 253
66 }
67
68 #endregion
69
70 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
71
72 private readonly Commander m_commander = new Commander("Terrain");
73
74 private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
75 new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
76
77 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
78
79 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
80 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
81
82 private Dictionary<Location, ITerrainChannel> m_channels;
83
84 private ITerrainChannel m_channel;
85 private Dictionary<string, ITerrainEffect> m_plugineffects;
86 private ITerrainChannel m_revert;
87 private Scene m_scene;
88 private bool m_tainted = false;
89
90 #region ICommandableModule Members
91
92 public ICommander CommandInterface
93 {
94 get { return m_commander; }
95 }
96
97 #endregion
98
99 #region IRegionModule Members
100
101 /// <summary>
102 /// Creates and initialises a terrain module for a region
103 /// </summary>
104 /// <param name="scene">Region initialising</param>
105 /// <param name="config">Config for the region</param>
106 public void Initialise(Scene scene, IConfigSource config)
107 {
108 m_scene = scene;
109
110 // Install terrain module in the simulator
111 if (m_scene.Heightmap == null)
112 {
113 lock (m_scene)
114 {
115 m_channel = new TerrainChannel();
116 m_scene.Heightmap = m_channel;
117 m_revert = new TerrainChannel();
118 UpdateRevertMap();
119 }
120 }
121 else
122 {
123 m_channel = m_scene.Heightmap;
124 m_revert = new TerrainChannel();
125 UpdateRevertMap();
126 }
127
128 m_scene.RegisterModuleInterface<ITerrainModule>(this);
129 m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
130 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
131 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
132 }
133
134 /// <summary>
135 /// Enables terrain module when called
136 /// </summary>
137 public void PostInitialise()
138 {
139 InstallDefaultEffects();
140 InstallInterfaces();
141 LoadPlugins();
142 }
143
144 public void Close()
145 {
146 }
147
148 public string Name
149 {
150 get { return "TerrainModule"; }
151 }
152
153 public bool IsSharedModule
154 {
155 get { return false; }
156 }
157
158 #endregion
159
160 #region ITerrainModule Members
161
162 /// <summary>
163 /// Loads a terrain file from disk and installs it in the scene.
164 /// </summary>
165 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
166 public void LoadFromFile(string filename)
167 {
168 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
169 {
170 if (filename.EndsWith(loader.Key))
171 {
172 lock (m_scene)
173 {
174 try
175 {
176 ITerrainChannel channel = loader.Value.LoadFile(filename);
177 m_scene.Heightmap = channel;
178 m_channel = channel;
179 UpdateRevertMap();
180 }
181 catch (NotImplementedException)
182 {
183 m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value +
184 " parser does not support file loading. (May be save only)");
185 throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value));
186 }
187 catch (FileNotFoundException)
188 {
189 m_log.Error(
190 "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
191 throw new TerrainException(
192 String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename));
193 }
194 }
195 CheckForTerrainUpdates();
196 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
197 return;
198 }
199 }
200 m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
201 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
202 }
203
204 /// <summary>
205 /// Saves the current heightmap to a specified file.
206 /// </summary>
207 /// <param name="filename">The destination filename</param>
208 public void SaveToFile(string filename)
209 {
210 try
211 {
212 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
213 {
214 if (filename.EndsWith(loader.Key))
215 {
216 loader.Value.SaveFile(filename, m_channel);
217 return;
218 }
219 }
220 }
221 catch (NotImplementedException)
222 {
223 m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
224 throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented"));
225 }
226 }
227
228 #region Plugin Loading Methods
229
230 private void LoadPlugins()
231 {
232 m_plugineffects = new Dictionary<string, ITerrainEffect>();
233 // Load the files in the Terrain/ dir
234 string[] files = Directory.GetFiles("Terrain");
235 foreach (string file in files)
236 {
237 m_log.Info("Loading effects in " + file);
238 try
239 {
240 Assembly library = Assembly.LoadFrom(file);
241 foreach (Type pluginType in library.GetTypes())
242 {
243 try
244 {
245 if (pluginType.IsAbstract || pluginType.IsNotPublic)
246 continue;
247
248 if (pluginType.GetInterface("ITerrainEffect", false) != null)
249 {
250 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
251 if (!m_plugineffects.ContainsKey(pluginType.Name))
252 {
253 m_plugineffects.Add(pluginType.Name, terEffect);
254 m_log.Info("E ... " + pluginType.Name);
255 } else
256 {
257 m_log.Warn("E ... " + pluginType.Name + " (Already added)");
258 }
259 }
260 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
261 {
262 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
263 m_loaders[terLoader.FileExtension] = terLoader;
264 m_log.Info("L ... " + pluginType.Name);
265 }
266 }
267 catch (AmbiguousMatchException)
268 {
269 }
270 }
271 }
272 catch (BadImageFormatException)
273 {
274 }
275 }
276 }
277
278 #endregion
279
280 #endregion
281
282 /// <summary>
283 /// Installs into terrain module the standard suite of brushes
284 /// </summary>
285 private void InstallDefaultEffects()
286 {
287 // Draggable Paint Brush Effects
288 m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere();
289 m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere();
290 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere();
291 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
292 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
293 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert);
294 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
295 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
296 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
297
298 // Area of effect selection effects
299 m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea();
300 m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea();
301 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea();
302 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea();
303 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea();
304 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert);
305
306 // Filesystem load/save loaders
307 m_loaders[".r32"] = new RAW32();
308 m_loaders[".f32"] = m_loaders[".r32"];
309 m_loaders[".ter"] = new Terragen();
310 m_loaders[".raw"] = new LLRAW();
311 m_loaders[".jpg"] = new JPEG();
312 m_loaders[".jpeg"] = m_loaders[".jpg"];
313 m_loaders[".bmp"] = new BMP();
314 m_loaders[".png"] = new PNG();
315 m_loaders[".gif"] = new GIF();
316 m_loaders[".tif"] = new TIFF();
317 m_loaders[".tiff"] = m_loaders[".tif"];
318 }
319
320 /// <summary>
321 /// Saves the current state of the region into the revert map buffer.
322 /// </summary>
323 public void UpdateRevertMap()
324 {
325 int x;
326 for (x = 0; x < m_channel.Width; x++)
327 {
328 int y;
329 for (y = 0; y < m_channel.Height; y++)
330 {
331 m_revert[x, y] = m_channel[x, y];
332 }
333 }
334 }
335
336 /// <summary>
337 /// Loads a tile from a larger terrain file and installs it into the region.
338 /// </summary>
339 /// <param name="filename">The terrain file to load</param>
340 /// <param name="fileWidth">The width of the file in units</param>
341 /// <param name="fileHeight">The height of the file in units</param>
342 /// <param name="fileStartX">Where to begin our slice</param>
343 /// <param name="fileStartY">Where to begin our slice</param>
344 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
345 {
346 int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX;
347 int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY;
348
349 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
350 {
351 // this region is included in the tile request
352 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
353 {
354 if (filename.EndsWith(loader.Key))
355 {
356 lock (m_scene)
357 {
358 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
359 fileWidth, fileHeight,
360 (int) Constants.RegionSize,
361 (int) Constants.RegionSize);
362 m_scene.Heightmap = channel;
363 m_channel = channel;
364 UpdateRevertMap();
365 }
366 return;
367 }
368 }
369 }
370 }
371
372 /// <summary>
373 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
374 /// </summary>
375 private void EventManager_OnTerrainTick()
376 {
377 if (m_tainted)
378 {
379 m_tainted = false;
380 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
381 m_scene.SaveTerrain();
382 m_scene.CreateTerrainTexture(true);
383 }
384 }
385
386 /// <summary>
387 /// Processes commandline input. Do not call directly.
388 /// </summary>
389 /// <param name="args">Commandline arguments</param>
390 private void EventManager_OnPluginConsole(string[] args)
391 {
392 if (args[0] == "terrain")
393 {
394 string[] tmpArgs = new string[args.Length - 2];
395 int i;
396 for (i = 2; i < args.Length; i++)
397 tmpArgs[i - 2] = args[i];
398
399 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
400 }
401 }
402
403 /// <summary>
404 /// Installs terrain brush hook to IClientAPI
405 /// </summary>
406 /// <param name="client"></param>
407 private void EventManager_OnNewClient(IClientAPI client)
408 {
409 client.OnModifyTerrain += client_OnModifyTerrain;
410 }
411
412 /// <summary>
413 /// Checks to see if the terrain has been modified since last check
414 /// </summary>
415 private void CheckForTerrainUpdates()
416 {
417 bool shouldTaint = false;
418 float[] serialised = m_channel.GetFloatsSerialised();
419 int x;
420 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
421 {
422 int y;
423 for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
424 {
425 if (m_channel.Tainted(x, y))
426 {
427 SendToClients(serialised, x, y);
428 shouldTaint = true;
429 }
430 }
431 }
432 if (shouldTaint)
433 {
434 m_tainted = true;
435 }
436 }
437
438 /// <summary>
439 /// Sends a copy of the current terrain to the scenes clients
440 /// </summary>
441 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
442 /// <param name="x">The patch corner to send</param>
443 /// <param name="y">The patch corner to send</param>
444 private void SendToClients(float[] serialised, int x, int y)
445 {
446 m_scene.ForEachClient(
447 delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); });
448 }
449
450 private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west,
451 float south, float east, IClientAPI remoteClient)
452 {
453 // Not a good permissions check, if in area mode, need to check the entire area.
454 if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0)))
455 {
456 if (north == south && east == west)
457 {
458 if (m_painteffects.ContainsKey((StandardTerrainEffects) action))
459 {
460 m_painteffects[(StandardTerrainEffects) action].PaintEffect(
461 m_channel, west, south, size, seconds);
462
463 CheckForTerrainUpdates();
464 }
465 else
466 {
467 m_log.Debug("Unknown terrain brush type " + action);
468 }
469 }
470 else
471 {
472 if (m_floodeffects.ContainsKey((StandardTerrainEffects) action))
473 {
474 bool[,] fillArea = new bool[m_channel.Width,m_channel.Height];
475 fillArea.Initialize();
476
477 int x;
478 for (x = 0; x < m_channel.Width; x++)
479 {
480 int y;
481 for (y = 0; y < m_channel.Height; y++)
482 {
483 if (x < east && x > west)
484 {
485 if (y < north && y > south)
486 {
487 fillArea[x, y] = true;
488 }
489 }
490 }
491 }
492
493 m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
494 m_channel, fillArea, size);
495
496 CheckForTerrainUpdates();
497 }
498 else
499 {
500 m_log.Debug("Unknown terrain flood type " + action);
501 }
502 }
503 }
504 }
505
506 #region Console Commands
507
508 private void InterfaceLoadFile(Object[] args)
509 {
510 LoadFromFile((string) args[0]);
511 CheckForTerrainUpdates();
512 }
513
514 private void InterfaceLoadTileFile(Object[] args)
515 {
516 LoadFromFile((string) args[0],
517 (int) args[1],
518 (int) args[2],
519 (int) args[3],
520 (int) args[4]);
521 CheckForTerrainUpdates();
522 }
523
524 private void InterfaceSaveFile(Object[] args)
525 {
526 SaveToFile((string) args[0]);
527 }
528
529 private void InterfaceBakeTerrain(Object[] args)
530 {
531 UpdateRevertMap();
532 }
533
534 private void InterfaceRevertTerrain(Object[] args)
535 {
536 int x, y;
537 for (x = 0; x < m_channel.Width; x++)
538 for (y = 0; y < m_channel.Height; y++)
539 m_channel[x, y] = m_revert[x, y];
540
541 CheckForTerrainUpdates();
542 }
543
544 private void InterfaceElevateTerrain(Object[] args)
545 {
546 int x, y;
547 for (x = 0; x < m_channel.Width; x++)
548 for (y = 0; y < m_channel.Height; y++)
549 m_channel[x, y] += (double) args[0];
550 CheckForTerrainUpdates();
551 }
552
553 private void InterfaceMultiplyTerrain(Object[] args)
554 {
555 int x, y;
556 for (x = 0; x < m_channel.Width; x++)
557 for (y = 0; y < m_channel.Height; y++)
558 m_channel[x, y] *= (double) args[0];
559 CheckForTerrainUpdates();
560 }
561
562 private void InterfaceLowerTerrain(Object[] args)
563 {
564 int x, y;
565 for (x = 0; x < m_channel.Width; x++)
566 for (y = 0; y < m_channel.Height; y++)
567 m_channel[x, y] -= (double) args[0];
568 CheckForTerrainUpdates();
569 }
570
571 private void InterfaceFillTerrain(Object[] args)
572 {
573 int x, y;
574
575 for (x = 0; x < m_channel.Width; x++)
576 for (y = 0; y < m_channel.Height; y++)
577 m_channel[x, y] = (double) args[0];
578 CheckForTerrainUpdates();
579 }
580
581 private void InterfaceShowDebugStats(Object[] args)
582 {
583 double max = Double.MinValue;
584 double min = double.MaxValue;
585 double avg;
586 double sum = 0;
587
588 int x;
589 for (x = 0; x < m_channel.Width; x++)
590 {
591 int y;
592 for (y = 0; y < m_channel.Height; y++)
593 {
594 sum += m_channel[x, y];
595 if (max < m_channel[x, y])
596 max = m_channel[x, y];
597 if (min > m_channel[x, y])
598 min = m_channel[x, y];
599 }
600 }
601
602 avg = sum / (m_channel.Height * m_channel.Width);
603
604 m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height);
605 m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum);
606 }
607
608 private void InterfaceEnableExperimentalBrushes(Object[] args)
609 {
610 if ((bool) args[0])
611 {
612 m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
613 m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
614 m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
615 }
616 else
617 {
618 InstallDefaultEffects();
619 }
620 }
621
622 private void InterfaceRunPluginEffect(Object[] args)
623 {
624 if ((string) args[0] == "list")
625 {
626 m_log.Info("List of loaded plugins");
627 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
628 {
629 m_log.Info(kvp.Key);
630 }
631 return;
632 }
633 if ((string) args[0] == "reload")
634 {
635 LoadPlugins();
636 return;
637 }
638 if (m_plugineffects.ContainsKey((string) args[0]))
639 {
640 m_plugineffects[(string) args[0]].RunEffect(m_channel);
641 CheckForTerrainUpdates();
642 }
643 else
644 {
645 m_log.Warn("No such plugin effect loaded.");
646 }
647 }
648
649 private void InstallInterfaces()
650 {
651 // Load / Save
652 string supportedFileExtensions = "";
653 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
654 supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")";
655
656 Command loadFromFileCommand =
657 new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file.");
658 loadFromFileCommand.AddArgument("filename",
659 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
660 supportedFileExtensions, "String");
661
662 Command saveToFileCommand =
663 new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file.");
664 saveToFileCommand.AddArgument("filename",
665 "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " +
666 supportedFileExtensions, "String");
667
668 Command loadFromTileCommand =
669 new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file.");
670 loadFromTileCommand.AddArgument("filename",
671 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
672 supportedFileExtensions, "String");
673 loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
674 loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
675 loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
676 "Integer");
677 loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
678 "Integer");
679
680 // Terrain adjustments
681 Command fillRegionCommand =
682 new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
683 fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.",
684 "Double");
685
686 Command elevateCommand =
687 new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount.");
688 elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double");
689
690 Command lowerCommand =
691 new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount.");
692 lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double");
693
694 Command multiplyCommand =
695 new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
696 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
697
698 Command bakeRegionCommand =
699 new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map.");
700 Command revertRegionCommand =
701 new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
702
703 // Debug
704 Command showDebugStatsCommand =
705 new Command("stats", InterfaceShowDebugStats,
706 "Shows some information about the regions heightmap for debugging purposes.");
707
708 Command experimentalBrushesCommand =
709 new Command("newbrushes", InterfaceEnableExperimentalBrushes,
710 "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time.");
711 experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
712
713 //Plugins
714 Command pluginRunCommand =
715 new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect");
716 pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String");
717
718 m_commander.RegisterCommand("load", loadFromFileCommand);
719 m_commander.RegisterCommand("load-tile", loadFromTileCommand);
720 m_commander.RegisterCommand("save", saveToFileCommand);
721 m_commander.RegisterCommand("fill", fillRegionCommand);
722 m_commander.RegisterCommand("elevate", elevateCommand);
723 m_commander.RegisterCommand("lower", lowerCommand);
724 m_commander.RegisterCommand("multiply", multiplyCommand);
725 m_commander.RegisterCommand("bake", bakeRegionCommand);
726 m_commander.RegisterCommand("revert", revertRegionCommand);
727 m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
728 m_commander.RegisterCommand("stats", showDebugStatsCommand);
729 m_commander.RegisterCommand("effect", pluginRunCommand);
730
731 // Add this to our scene so scripts can call these functions
732 m_scene.RegisterModuleCommander("Terrain", m_commander);
733 }
734
735 #endregion
736 }
737} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs
new file mode 100644
index 0000000..b593717
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs
@@ -0,0 +1,133 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.World.Terrain
32{
33 public static class TerrainUtil
34 {
35 public static double MetersToSphericalStrength(double size)
36 {
37 return Math.Pow(2, size);
38 }
39
40 public static double SphericalFactor(double x, double y, double rx, double ry, double size)
41 {
42 return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
43 }
44
45 public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
46 {
47 int w = map.Width;
48 int h = map.Height;
49
50 if (x > w - 2.0)
51 x = w - 2.0;
52 if (y > h - 2.0)
53 y = h - 2.0;
54 if (x < 0.0)
55 x = 0.0;
56 if (y < 0.0)
57 y = 0.0;
58
59 int stepSize = 1;
60 double h00 = map[(int) x, (int) y];
61 double h10 = map[(int) x + stepSize, (int) y];
62 double h01 = map[(int) x, (int) y + stepSize];
63 double h11 = map[(int) x + stepSize, (int) y + stepSize];
64 double h1 = h00;
65 double h2 = h10;
66 double h3 = h01;
67 double h4 = h11;
68 double a00 = h1;
69 double a10 = h2 - h1;
70 double a01 = h3 - h1;
71 double a11 = h1 - h2 - h3 + h4;
72 double partialx = x - (int) x;
73 double partialz = y - (int) y;
74 double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
75 return hi;
76 }
77
78 private static double Noise(double x, double y)
79 {
80 int n = (int) x + (int) (y * 749);
81 n = (n << 13) ^ n;
82 return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
83 }
84
85 private static double SmoothedNoise1(double x, double y)
86 {
87 double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16;
88 double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8;
89 double center = Noise(x, y) / 4;
90 return corners + sides + center;
91 }
92
93 private static double Interpolate(double x, double y, double z)
94 {
95 return (x * (1.0 - z)) + (y * z);
96 }
97
98 private static double InterpolatedNoise(double x, double y)
99 {
100 int integer_X = (int) (x);
101 double fractional_X = x - integer_X;
102
103 int integer_Y = (int) y;
104 double fractional_Y = y - integer_Y;
105
106 double v1 = SmoothedNoise1(integer_X, integer_Y);
107 double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
108 double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
109 double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
110
111 double i1 = Interpolate(v1, v2, fractional_X);
112 double i2 = Interpolate(v3, v4, fractional_X);
113
114 return Interpolate(i1, i2, fractional_Y);
115 }
116
117 public static double PerlinNoise2D(double x, double y, int octaves, double persistence)
118 {
119 double frequency = 0.0;
120 double amplitude = 0.0;
121 double total = 0.0;
122
123 for (int i = 0; i < octaves; i++)
124 {
125 frequency = Math.Pow(2, i);
126 amplitude = Math.Pow(persistence, i);
127
128 total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
129 }
130 return total;
131 }
132 }
133} \ No newline at end of file