29 using System.Collections.Generic;
31 using System.Reflection;
35 using OpenMetaverse.Imaging;
36 using OpenSim.Framework;
37 using OpenSim.Region.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
41 namespace OpenSim.
Region.CoreModules.
World.LegacyMap
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 public HSV(
float h,
float s,
float v)
64 float max = Math.Max(Math.Max(r, g), b);
65 float min = Math.Min(Math.Min(r, g), b);
66 float diff = max - min;
68 if (max == min) h = 0f;
69 else if (max == r) h = (g - b) / diff * 60f;
70 else if (max == g) h = (b - r) / diff * 60f + 120f;
71 else h = (r - g) / diff * 60f + 240f;
72 if (h < 0f) h += 360f;
74 if (max == 0f) s = 0f;
83 if (s < 0f) m_log.Debug(
"S < 0: " + s);
84 else if (s > 1f) m_log.Debug(
"S > 1: " + s);
85 if (v < 0f) m_log.Debug(
"V < 0: " + v);
86 else if (v > 1f) m_log.Debug(
"V > 1: " + v);
89 int sector = (int)f % 6;
91 int pi = (int)(v * (1f - s) * 255f);
92 int qi = (int)(v * (1f - s * f) * 255f);
93 int ti = (int)(v * (1f - (1f - f) * s) * 255f);
94 int vi = (int)(v * 255f);
97 if (pi > 255) pi = 255;
99 if (qi > 255) qi = 255;
101 if (ti > 255) ti = 255;
103 if (vi > 255) vi = 255;
108 return Color.FromArgb(vi, ti, pi);
110 return Color.FromArgb(qi, vi, pi);
112 return Color.FromArgb(pi, vi, ti);
114 return Color.FromArgb(pi, qi, vi);
116 return Color.FromArgb(ti, pi, vi);
118 return Color.FromArgb(vi, pi, qi);
127 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128 private static readonly
string LogHeader =
"[TEXTURED MAPTILE RENDERER]";
132 private static readonly
UUID defaultTerrainTexture1 =
new UUID(
"0bc58228-74a0-7e83-89bc-5c23464bcec5");
133 private static readonly Color defaultColor1 = Color.FromArgb(165, 137, 118);
134 private static readonly
UUID defaultTerrainTexture2 =
new UUID(
"63338ede-0037-c4fd-855b-015d77112fc8");
135 private static readonly Color defaultColor2 = Color.FromArgb(69, 89, 49);
136 private static readonly
UUID defaultTerrainTexture3 =
new UUID(
"303cd381-8560-7579-23f1-f0a880799740");
137 private static readonly Color defaultColor3 = Color.FromArgb(162, 154, 141);
138 private static readonly
UUID defaultTerrainTexture4 =
new UUID(
"53a2f406-4895-1d13-d541-d2e3b86bc19c");
139 private static readonly Color defaultColor4 = Color.FromArgb(200, 200, 200);
141 private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95);
146 private Scene m_scene;
153 private Dictionary<UUID, Color> m_mapping;
160 m_mapping =
new Dictionary<UUID,Color>();
161 m_mapping.Add(defaultTerrainTexture1, defaultColor1);
162 m_mapping.Add(defaultTerrainTexture2, defaultColor2);
163 m_mapping.Add(defaultTerrainTexture3, defaultColor3);
164 m_mapping.Add(defaultTerrainTexture4, defaultColor4);
165 m_mapping.Add(Util.BLANK_TEXTURE_UUID, Color.White);
175 private Bitmap fetchTexture(UUID
id)
177 AssetBase asset = m_scene.AssetService.Get(id.ToString());
178 m_log.DebugFormat(
"{0} Fetched texture {1}, found: {2}", LogHeader, id, asset != null);
179 if (asset == null)
return null;
181 ManagedImage managedImage;
186 if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image))
187 return new Bitmap(image);
191 catch (DllNotFoundException)
193 m_log.ErrorFormat(
"{0} OpenJpeg is not installed correctly on this system. Asset Data is empty for {1}", LogHeader, id);
195 catch (IndexOutOfRangeException)
197 m_log.ErrorFormat(
"{0} OpenJpeg was unable to encode this. Asset Data is empty for {1}", LogHeader, id);
201 m_log.ErrorFormat(
"{0} OpenJpeg was unable to encode this. Asset Data is empty for {1}", LogHeader, id);
208 private Color computeAverageColor(Bitmap bmp)
213 int r = 0, g = 0, b = 0;
214 for (
int y = 0; y < bmp.Height; ++y)
216 for (
int x = 0; x < bmp.Width; ++x)
218 Color c = bmp.GetPixel(x, y);
219 r += (int)c.R & 0xff;
220 g += (
int)c.G & 0xff;
221 b += (int)c.B & 0xff;
225 int pixels = bmp.Width * bmp.Height;
226 return Color.FromArgb(r / pixels, g / pixels, b / pixels);
231 private Color computeAverageColor(UUID textureID, Color defaultColor) {
232 if (textureID ==
UUID.Zero)
return defaultColor;
233 if (m_mapping.ContainsKey(textureID))
return m_mapping[textureID];
237 using (Bitmap bmp = fetchTexture(textureID))
239 color = bmp == null ? defaultColor : computeAverageColor(bmp);
241 m_mapping[textureID] = color;
251 private float S(
float v) {
252 return (v * v * (3f - 2f * v));
256 private HSV interpolateHSV(ref HSV c1, ref HSV c2,
float ratio) {
257 if (ratio <= 0f)
return c1;
258 if (ratio >= 1f)
return c2;
263 if (c1.h - c2.h > 180f) c1.h -= 360f;
264 else if (c2.h - c1.h > 180f) c1.h += 360f;
266 return new HSV(c1.h * (1f - ratio) + c2.h * ratio,
267 c1.s * (1f - ratio) + c2.s * ratio,
268 c1.v * (1f - ratio) + c2.v * ratio);
275 return (
float)(hm[x, y] * .444 + (hm[x + 1, y] + hm[x, y + 1]) * .222 + hm[x + 1, y +1] * .112);
277 return (
float)hm[x, y];
283 int tc = Environment.TickCount;
284 m_log.DebugFormat(
"{0} Generating Maptile Step 1: Terrain", LogHeader);
288 if (mapbmp.Width != hm.Width || mapbmp.Height != hm.Height)
290 m_log.ErrorFormat(
"{0} TerrainToBitmap. Passed bitmap wrong dimensions. passed=<{1},{2}>, size=<{3},{4}>",
291 "[TEXTURED MAP TILE RENDERER]", mapbmp.Width, mapbmp.Height, hm.Width, hm.Height);
307 float levelNEhigh = (
float)settings.Elevation2NE;
310 float levelNWhigh = (
float)settings.Elevation2NW;
313 float levelSEhigh = (
float)settings.Elevation2SE;
316 float levelSWhigh = (
float)settings.Elevation2SW;
320 for (
int x = 0; x < hm.Width; x++)
322 float columnRatio = x / (hm.Width - 1);
323 for (
int y = 0; y < hm.Height; y++)
325 float rowRatio = y / (hm.Height - 1);
328 int yr = (hm.Height - 1) - y;
330 float heightvalue = getHeight(m_scene.Heightmap, x, y);
331 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
334 if (heightvalue > waterHeight)
344 (float)TerrainUtil.InterpolatedNoise(x + 33, y + 43) * 1.5f + 1.5f +
345 S(
S((
float)TerrainUtil.InterpolatedNoise(x / 8.0, y / 8.0) * .5f + .5f)) * 10f;
349 float low = levelSWlow * (1f - rowRatio) * (1f - columnRatio) +
350 levelSElow * (1f - rowRatio) * columnRatio +
351 levelNWlow * rowRatio * (1f - columnRatio) +
352 levelNElow * rowRatio * columnRatio;
353 float high = levelSWhigh * (1f - rowRatio) * (1f - columnRatio) +
354 levelSEhigh * (1f - rowRatio) * columnRatio +
355 levelNWhigh * rowRatio * (1f - columnRatio) +
356 levelNEhigh * rowRatio * columnRatio;
366 if (hmod <= low) hsv = hsv1;
367 else if (hmod >= high) hsv = hsv4;
372 hmod = (hmod - low) / (high - low);
374 if (hmod < 1f / 3f) hsv = interpolateHSV(ref hsv1, ref hsv2, hmod * 3f);
375 else if (hmod < 2f / 3f) hsv = interpolateHSV(ref hsv2, ref hsv3, (hmod * 3f) - 1f);
376 else hsv = interpolateHSV(ref hsv3, ref hsv4, (hmod * 3f) - 2f);
380 if (x < (hm.Width - 1) && y < (hm.Height - 1))
382 float hfvaluecompare = getHeight(m_scene.Heightmap, x + 1, y + 1);
383 if (Single.IsInfinity(hfvaluecompare) || Single.IsNaN(hfvaluecompare))
386 float hfdiff = heightvalue - hfvaluecompare;
390 float highlightfactor = 0.18f;
393 hsv.s = (hsv.s - (hfdiff * highlightfactor) > 0f) ? hsv.s - (hfdiff * highlightfactor) : 0f;
394 hsv.v = (hsv.v + (hfdiff * highlightfactor) < 1f) ? hsv.v + (hfdiff * highlightfactor) : 1f;
396 else if (hfdiff < -0.02f)
400 hsv.s = (hsv.s + hfdiff > 0f) ? hsv.
s + hfdiff : 0f;
401 hsv.
v = (hsv.
v + hfdiff > 0f) ? hsv.v + hfdiff : 0f;
404 mapbmp.SetPixel(x, yr, hsv.toColor());
410 heightvalue = waterHeight - heightvalue;
411 if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
413 else if (heightvalue > 19f)
415 else if (heightvalue < 0f)
418 heightvalue = 100f - (heightvalue * 100f) / 19f;
420 mapbmp.SetPixel(x, yr, WATER_COLOR);
425 m_log.Debug(
"[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) +
" ms");
void Initialise(Scene scene, IConfigSource source)
void TerrainToBitmap(Bitmap mapbmp)
OpenSim.Framework.RegionSettings RegionSettings
HSV(float h, float s, float v)
Asset class. All Assets are reference by this class or a class derived from this class ...