28 using System.Reflection;
31 using OpenSim.Region.Framework.Interfaces;
38 protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 public abstract string GetUsage();
57 data.shape = String.Empty;
58 data.bevel = String.Empty;
63 result =
"Usage: " + GetUsage();
67 result = this.parseFloat(args[3], out data.elevation);
69 if (result ==
String.Empty)
72 while(++index < args.Length && result ==
String.Empty)
76 if (arg.StartsWith(
"-rec=") || arg.StartsWith(
"-ell="))
78 if (data.shape !=
String.Empty)
80 result =
"Only 1 '-rec' or '-ell' parameter is permitted.";
84 data.shape = arg.StartsWith(
"-ell=") ?
"ellipse" :
"rectangle";
85 val = arg.Substring(arg.IndexOf(
"=") + 1);
86 string[] coords = val.Split(
new char[] {
','});
87 if ((coords.Length < 3) || (coords.Length > 4))
89 result = String.Format(
"Bad format for shape parameter {0}", arg);
93 result = this.parseInt(coords[0], out data.x0);
94 if (result ==
String.Empty)
96 result = this.parseInt(coords[1], out data.y0);
98 if (result ==
String.Empty)
100 result = this.parseInt(coords[2], out data.dx);
102 if (result ==
String.Empty)
104 if (coords.Length == 4)
106 result = this.parseInt(coords[3], out data.dy);
113 if (result ==
String.Empty)
115 if ((data.dx <= 0) || (data.dy <= 0))
117 result =
"Shape sizes must be positive integers";
122 result = String.Format(
"Bad value in shape parameters {0}", arg);
127 else if (arg.StartsWith(
"-taper="))
129 if (data.bevel !=
String.Empty)
131 result =
"Only 1 '-taper' parameter is permitted.";
135 data.bevel =
"taper";
136 val = arg.Substring(arg.IndexOf(
"=") + 1);
137 result = this.parseFloat(val, out data.bevelevation);
138 if (result !=
String.Empty)
140 result = String.Format(
"Bad format for taper parameter {0}", arg);
146 result = String.Format(
"Unrecognized parameter {0}", arg);
157 if (Double.TryParse(s, out d))
162 result = String.Empty;
164 catch(InvalidCastException)
166 result = String.Format(
"{0} is invalid", s);
173 result = String.Format(
"{0} is invalid", s);
181 if (Int32.TryParse(s, out i))
183 result = String.Empty;
187 result = String.Format(
"{0} is invalid", s);
199 if (data.
shape ==
"ellipse")
201 mask = this.ellipticalMask(data.dx, data.dy);
202 xMax = mask.GetLength(0);
203 yMax = mask.GetLength(1);
204 xMid = xMax / 2 + xMax % 2;
205 yMid = yMax / 2 + yMax % 2;
209 mask = this.rectangularMask(data.dx, data.dy);
210 xMax = mask.GetLength(0);
211 yMax = mask.GetLength(1);
216 double[,] buffer = map.GetDoubles();
220 int yPos = data.y0 + yDim - yMid;
221 if ((yPos >= 0) && (yPos < map.Height))
226 int xPos = data.x0 + xDim - xMid;
227 if ((xPos >= 0) && (xPos < map.Width) && (mask[xDim, yDim]))
229 double endElevation = this.operate(buffer, data, xPos, yPos);
230 map[xPos, yPos] = endElevation;
244 if (data.
bevel ==
"taper")
246 if (data.
shape ==
"ellipse")
248 deltaX = x - data.x0;
249 deltaY = y - data.y0;
252 factor = (double)((deltaX * deltaX) + (deltaY * deltaY));
253 factor /= ((xMax * xMax) + (yMax * yMax));
258 xMax = data.dx / 2 + data.dx % 2;
259 yMax = data.dy / 2 + data.dy % 2;
260 deltaX = Math.Abs(data.x0 + xMax - x);
261 deltaY = Math.Abs(data.y0 + yMax - y);
262 factor = Math.Max(((double)(deltaY) / yMax), ((
double)(deltaX) / xMax));
272 private bool[,] rectangularMask(
int xSize,
int ySize)
274 bool[,] mask =
new bool[xSize, ySize];
281 mask[xPos, yPos] =
true;
291 private bool[,] ellipticalMask(
int xRadius,
int yRadius)
293 long twoASquared = 2L * xRadius * xRadius;
294 long twoBSquared = 2L * yRadius * yRadius;
296 bool[,] mask =
new bool[2 * xRadius + 1, 2 * yRadius + 1];
298 long ellipseError = 0L;
299 long stoppingX = twoBSquared * xRadius;
301 long xChange = yRadius * yRadius * (1L - 2L * xRadius);
302 long yChange = xRadius * xRadius;
308 while(stoppingX >= stoppingY)
310 int yUpper = yRadius + yPos;
311 int yLower = yRadius - yPos;
316 mask[xRadius + xNow, yUpper] =
true;
317 mask[xRadius - xNow, yUpper] =
true;
318 mask[xRadius + xNow, yLower] =
true;
319 mask[xRadius - xNow, yLower] =
true;
323 stoppingY += twoASquared;
324 ellipseError += yChange;
325 yChange += twoASquared;
326 if ((2L * ellipseError + xChange) > 0L)
329 stoppingX -= twoBSquared;
330 ellipseError += xChange;
331 xChange += twoBSquared;
338 xChange = yRadius * yRadius;
339 yChange = xRadius * xRadius * (1L - 2L * yRadius);
343 stoppingY = twoASquared * yRadius;
345 while(stoppingX <= stoppingY)
347 int xUpper = xRadius + xPos;
348 int xLower = xRadius - xPos;
353 mask[xUpper, yRadius + yNow] =
true;
354 mask[xUpper, yRadius - yNow] =
true;
355 mask[xLower, yRadius + yNow] =
true;
356 mask[xLower, yRadius - yNow] =
true;
360 stoppingX += twoBSquared;
361 ellipseError += xChange;
362 xChange += twoBSquared;
363 if ((2L * ellipseError + yChange) > 0L)
366 stoppingY -= twoASquared;
367 ellipseError += yChange;
368 yChange += twoASquared;
String parseParameters(string[] args, out TerrainModifierData data)
void applyModification(ITerrainChannel map, TerrainModifierData data)
double computeBevel(TerrainModifierData data, int x, int y)
string parseFloat(String s, out float f)
TerrainModifier(ITerrainModule module)
delegate void ModifyTerrain(UUID user, float height, float seconds, byte size, byte action, float north, float west, float south, float east, UUID agentId)
string parseInt(String s, out int i)