diff options
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | 380 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs (renamed from OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs) | 88 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 7 |
6 files changed, 266 insertions, 231 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index 8101ca2..87ca327 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | |||
@@ -57,14 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile | |||
57 | 57 | ||
58 | public void Initialise(IConfigSource config) | 58 | public void Initialise(IConfigSource config) |
59 | { | 59 | { |
60 | // This can be reduced later as the loader will determine | ||
61 | // whether we are needed | ||
62 | if (config.Configs["Profile"] != null) | ||
63 | { | ||
64 | if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule") | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); | 60 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); |
69 | m_Enabled = true; | 61 | m_Enabled = true; |
70 | } | 62 | } |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index d2bbea3..3b84d57 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | |||
@@ -73,7 +73,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
73 | "set terrain heights <corner> <min> <max> [<x>] [<y>]", | 73 | "set terrain heights <corner> <min> <max> [<x>] [<y>]", |
74 | "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + | 74 | "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + |
75 | "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + | 75 | "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + |
76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.", | 76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", |
77 | consoleSetTerrainHeights); | 77 | consoleSetTerrainHeights); |
78 | 78 | ||
79 | m_module.Scene.AddCommand( | 79 | m_module.Scene.AddCommand( |
@@ -143,6 +143,16 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
143 | 143 | ||
144 | switch (corner) | 144 | switch (corner) |
145 | { | 145 | { |
146 | case -1: | ||
147 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; | ||
148 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; | ||
149 | m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue; | ||
150 | m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue; | ||
151 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue; | ||
152 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue; | ||
153 | m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue; | ||
154 | m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; | ||
155 | break; | ||
146 | case 0: | 156 | case 0: |
147 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; | 157 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; |
148 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; | 158 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 71c71e6..7a0db26 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | |||
@@ -180,8 +180,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
180 | // fileHeight = sztmp; | 180 | // fileHeight = sztmp; |
181 | bs.ReadInt16(); | 181 | bs.ReadInt16(); |
182 | bs.ReadInt16(); | 182 | bs.ReadInt16(); |
183 | bs.ReadInt16(); | ||
184 | bs.ReadInt16(); | ||
185 | break; | 183 | break; |
186 | case "XPTS": | 184 | case "XPTS": |
187 | // fileWidth = bs.ReadInt16(); | 185 | // fileWidth = bs.ReadInt16(); |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 7bf675d..91252f7 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | |||
@@ -84,218 +84,234 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
84 | Debug.Assert(heightRanges.Length == 4); | 84 | Debug.Assert(heightRanges.Length == 4); |
85 | 85 | ||
86 | Bitmap[] detailTexture = new Bitmap[4]; | 86 | Bitmap[] detailTexture = new Bitmap[4]; |
87 | Bitmap output = null; | ||
88 | BitmapData outputData = null; | ||
87 | 89 | ||
88 | if (textureTerrain) | 90 | try |
89 | { | 91 | { |
90 | // Swap empty terrain textureIDs with default IDs | 92 | if (textureTerrain) |
91 | for (int i = 0; i < textureIDs.Length; i++) | ||
92 | { | 93 | { |
93 | if (textureIDs[i] == UUID.Zero) | 94 | // Swap empty terrain textureIDs with default IDs |
94 | textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; | 95 | for (int i = 0; i < textureIDs.Length; i++) |
95 | } | ||
96 | |||
97 | #region Texture Fetching | ||
98 | |||
99 | if (assetService != null) | ||
100 | { | ||
101 | for (int i = 0; i < 4; i++) | ||
102 | { | 96 | { |
103 | AssetBase asset; | 97 | if (textureIDs[i] == UUID.Zero) |
104 | UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); | 98 | textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; |
105 | 99 | } | |
106 | // Try to fetch a cached copy of the decoded/resized version of this texture | 100 | |
107 | asset = assetService.GetCached(cacheID.ToString()); | 101 | #region Texture Fetching |
108 | if (asset != null) | 102 | |
109 | { | 103 | if (assetService != null) |
110 | try | 104 | { |
111 | { | 105 | for (int i = 0; i < 4; i++) |
112 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) | ||
113 | detailTexture[i] = (Bitmap)Image.FromStream(stream); | ||
114 | } | ||
115 | catch (Exception ex) | ||
116 | { | ||
117 | m_log.Warn("Failed to decode cached terrain texture " + cacheID + | ||
118 | " (textureID: " + textureIDs[i] + "): " + ex.Message); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | if (detailTexture[i] == null) | ||
123 | { | 106 | { |
124 | // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG | 107 | AssetBase asset; |
125 | asset = assetService.Get(textureIDs[i].ToString()); | 108 | UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); |
109 | |||
110 | // Try to fetch a cached copy of the decoded/resized version of this texture | ||
111 | asset = assetService.GetCached(cacheID.ToString()); | ||
126 | if (asset != null) | 112 | if (asset != null) |
127 | { | 113 | { |
128 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } | 114 | try |
115 | { | ||
116 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) | ||
117 | detailTexture[i] = (Bitmap)Image.FromStream(stream); | ||
118 | } | ||
129 | catch (Exception ex) | 119 | catch (Exception ex) |
130 | { | 120 | { |
131 | m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); | 121 | m_log.Warn("Failed to decode cached terrain texture " + cacheID + |
122 | " (textureID: " + textureIDs[i] + "): " + ex.Message); | ||
132 | } | 123 | } |
133 | } | 124 | } |
134 | 125 | ||
135 | if (detailTexture[i] != null) | 126 | if (detailTexture[i] == null) |
136 | { | 127 | { |
137 | Bitmap bitmap = detailTexture[i]; | 128 | // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG |
138 | 129 | asset = assetService.Get(textureIDs[i].ToString()); | |
139 | // Make sure this texture is the correct size, otherwise resize | 130 | if (asset != null) |
140 | if (bitmap.Width != 256 || bitmap.Height != 256) | ||
141 | bitmap = ImageUtils.ResizeImage(bitmap, 256, 256); | ||
142 | |||
143 | // Save the decoded and resized texture to the cache | ||
144 | byte[] data; | ||
145 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) | ||
146 | { | 131 | { |
147 | bitmap.Save(stream, ImageFormat.Png); | 132 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } |
148 | data = stream.ToArray(); | 133 | catch (Exception ex) |
134 | { | ||
135 | m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); | ||
136 | } | ||
149 | } | 137 | } |
150 | 138 | ||
151 | // Cache a PNG copy of this terrain texture | 139 | if (detailTexture[i] != null) |
152 | AssetBase newAsset = new AssetBase | ||
153 | { | 140 | { |
154 | Data = data, | 141 | Bitmap bitmap = detailTexture[i]; |
155 | Description = "PNG", | 142 | |
156 | Flags = AssetFlags.Collectable, | 143 | // Make sure this texture is the correct size, otherwise resize |
157 | FullID = cacheID, | 144 | if (bitmap.Width != 256 || bitmap.Height != 256) |
158 | ID = cacheID.ToString(), | 145 | { |
159 | Local = true, | 146 | using (Bitmap origBitmap = bitmap) |
160 | Name = String.Empty, | 147 | { |
161 | Temporary = true, | 148 | bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256); |
162 | Type = (sbyte)AssetType.Unknown | 149 | } |
163 | }; | 150 | } |
164 | newAsset.Metadata.ContentType = "image/png"; | 151 | |
165 | assetService.Store(newAsset); | 152 | // Save the decoded and resized texture to the cache |
153 | byte[] data; | ||
154 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) | ||
155 | { | ||
156 | bitmap.Save(stream, ImageFormat.Png); | ||
157 | data = stream.ToArray(); | ||
158 | } | ||
159 | |||
160 | // Cache a PNG copy of this terrain texture | ||
161 | AssetBase newAsset = new AssetBase | ||
162 | { | ||
163 | Data = data, | ||
164 | Description = "PNG", | ||
165 | Flags = AssetFlags.Collectable, | ||
166 | FullID = cacheID, | ||
167 | ID = cacheID.ToString(), | ||
168 | Local = true, | ||
169 | Name = String.Empty, | ||
170 | Temporary = true, | ||
171 | Type = (sbyte)AssetType.Unknown | ||
172 | }; | ||
173 | newAsset.Metadata.ContentType = "image/png"; | ||
174 | assetService.Store(newAsset); | ||
175 | } | ||
166 | } | 176 | } |
167 | } | 177 | } |
168 | } | 178 | } |
179 | |||
180 | #endregion Texture Fetching | ||
169 | } | 181 | } |
170 | 182 | ||
171 | #endregion Texture Fetching | 183 | // Fill in any missing textures with a solid color |
172 | } | 184 | for (int i = 0; i < 4; i++) |
173 | |||
174 | // Fill in any missing textures with a solid color | ||
175 | for (int i = 0; i < 4; i++) | ||
176 | { | ||
177 | if (detailTexture[i] == null) | ||
178 | { | 185 | { |
179 | // Create a solid color texture for this layer | 186 | if (detailTexture[i] == null) |
180 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
181 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) | ||
182 | { | 187 | { |
183 | using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) | 188 | // Create a solid color texture for this layer |
184 | gfx.FillRectangle(brush, 0, 0, 256, 256); | 189 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); |
190 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) | ||
191 | { | ||
192 | using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) | ||
193 | gfx.FillRectangle(brush, 0, 0, 256, 256); | ||
194 | } | ||
185 | } | 195 | } |
186 | } | 196 | } |
187 | } | 197 | |
188 | 198 | #region Layer Map | |
189 | #region Layer Map | 199 | |
190 | 200 | float[] layermap = new float[256 * 256]; | |
191 | float[] layermap = new float[256 * 256]; | 201 | |
192 | |||
193 | for (int y = 0; y < 256; y++) | ||
194 | { | ||
195 | for (int x = 0; x < 256; x++) | ||
196 | { | ||
197 | float height = heightmap[y * 256 + x]; | ||
198 | |||
199 | float pctX = (float)x / 255f; | ||
200 | float pctY = (float)y / 255f; | ||
201 | |||
202 | // Use bilinear interpolation between the four corners of start height and | ||
203 | // height range to select the current values at this position | ||
204 | float startHeight = ImageUtils.Bilinear( | ||
205 | startHeights[0], | ||
206 | startHeights[2], | ||
207 | startHeights[1], | ||
208 | startHeights[3], | ||
209 | pctX, pctY); | ||
210 | startHeight = Utils.Clamp(startHeight, 0f, 255f); | ||
211 | |||
212 | float heightRange = ImageUtils.Bilinear( | ||
213 | heightRanges[0], | ||
214 | heightRanges[2], | ||
215 | heightRanges[1], | ||
216 | heightRanges[3], | ||
217 | pctX, pctY); | ||
218 | heightRange = Utils.Clamp(heightRange, 0f, 255f); | ||
219 | |||
220 | // Generate two frequencies of perlin noise based on our global position | ||
221 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting | ||
222 | Vector3 vec = new Vector3 | ||
223 | ( | ||
224 | ((float)regionPosition.X + x) * 0.20319f, | ||
225 | ((float)regionPosition.Y + y) * 0.20319f, | ||
226 | height * 0.25f | ||
227 | ); | ||
228 | |||
229 | float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; | ||
230 | float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; | ||
231 | float noise = (lowFreq + highFreq) * 2f; | ||
232 | |||
233 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it | ||
234 | float layer = ((height + noise - startHeight) / heightRange) * 4f; | ||
235 | if (Single.IsNaN(layer)) layer = 0f; | ||
236 | layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | #endregion Layer Map | ||
241 | |||
242 | #region Texture Compositing | ||
243 | |||
244 | Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
245 | BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); | ||
246 | |||
247 | unsafe | ||
248 | { | ||
249 | // Get handles to all of the texture data arrays | ||
250 | BitmapData[] datas = new BitmapData[] | ||
251 | { | ||
252 | detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), | ||
253 | detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), | ||
254 | detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), | ||
255 | detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) | ||
256 | }; | ||
257 | |||
258 | int[] comps = new int[] | ||
259 | { | ||
260 | (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
261 | (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
262 | (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
263 | (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 | ||
264 | }; | ||
265 | |||
266 | for (int y = 0; y < 256; y++) | 202 | for (int y = 0; y < 256; y++) |
267 | { | 203 | { |
268 | for (int x = 0; x < 256; x++) | 204 | for (int x = 0; x < 256; x++) |
269 | { | 205 | { |
270 | float layer = layermap[y * 256 + x]; | 206 | float height = heightmap[y * 256 + x]; |
271 | 207 | ||
272 | // Select two textures | 208 | float pctX = (float)x / 255f; |
273 | int l0 = (int)Math.Floor(layer); | 209 | float pctY = (float)y / 255f; |
274 | int l1 = Math.Min(l0 + 1, 3); | 210 | |
275 | 211 | // Use bilinear interpolation between the four corners of start height and | |
276 | byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; | 212 | // height range to select the current values at this position |
277 | byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; | 213 | float startHeight = ImageUtils.Bilinear( |
278 | byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; | 214 | startHeights[0], |
279 | 215 | startHeights[2], | |
280 | float aB = *(ptrA + 0); | 216 | startHeights[1], |
281 | float aG = *(ptrA + 1); | 217 | startHeights[3], |
282 | float aR = *(ptrA + 2); | 218 | pctX, pctY); |
283 | 219 | startHeight = Utils.Clamp(startHeight, 0f, 255f); | |
284 | float bB = *(ptrB + 0); | 220 | |
285 | float bG = *(ptrB + 1); | 221 | float heightRange = ImageUtils.Bilinear( |
286 | float bR = *(ptrB + 2); | 222 | heightRanges[0], |
287 | 223 | heightRanges[2], | |
288 | float layerDiff = layer - l0; | 224 | heightRanges[1], |
289 | 225 | heightRanges[3], | |
290 | // Interpolate between the two selected textures | 226 | pctX, pctY); |
291 | *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); | 227 | heightRange = Utils.Clamp(heightRange, 0f, 255f); |
292 | *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); | 228 | |
293 | *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); | 229 | // Generate two frequencies of perlin noise based on our global position |
230 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting | ||
231 | Vector3 vec = new Vector3 | ||
232 | ( | ||
233 | ((float)regionPosition.X + x) * 0.20319f, | ||
234 | ((float)regionPosition.Y + y) * 0.20319f, | ||
235 | height * 0.25f | ||
236 | ); | ||
237 | |||
238 | float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; | ||
239 | float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; | ||
240 | float noise = (lowFreq + highFreq) * 2f; | ||
241 | |||
242 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it | ||
243 | float layer = ((height + noise - startHeight) / heightRange) * 4f; | ||
244 | if (Single.IsNaN(layer)) layer = 0f; | ||
245 | layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); | ||
294 | } | 246 | } |
295 | } | 247 | } |
296 | 248 | ||
249 | #endregion Layer Map | ||
250 | |||
251 | #region Texture Compositing | ||
252 | |||
253 | output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
254 | outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); | ||
255 | |||
256 | unsafe | ||
257 | { | ||
258 | // Get handles to all of the texture data arrays | ||
259 | BitmapData[] datas = new BitmapData[] | ||
260 | { | ||
261 | detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), | ||
262 | detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), | ||
263 | detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), | ||
264 | detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) | ||
265 | }; | ||
266 | |||
267 | int[] comps = new int[] | ||
268 | { | ||
269 | (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
270 | (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
271 | (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
272 | (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 | ||
273 | }; | ||
274 | |||
275 | for (int y = 0; y < 256; y++) | ||
276 | { | ||
277 | for (int x = 0; x < 256; x++) | ||
278 | { | ||
279 | float layer = layermap[y * 256 + x]; | ||
280 | |||
281 | // Select two textures | ||
282 | int l0 = (int)Math.Floor(layer); | ||
283 | int l1 = Math.Min(l0 + 1, 3); | ||
284 | |||
285 | byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; | ||
286 | byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; | ||
287 | byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; | ||
288 | |||
289 | float aB = *(ptrA + 0); | ||
290 | float aG = *(ptrA + 1); | ||
291 | float aR = *(ptrA + 2); | ||
292 | |||
293 | float bB = *(ptrB + 0); | ||
294 | float bG = *(ptrB + 1); | ||
295 | float bR = *(ptrB + 2); | ||
296 | |||
297 | float layerDiff = layer - l0; | ||
298 | |||
299 | // Interpolate between the two selected textures | ||
300 | *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); | ||
301 | *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); | ||
302 | *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | for (int i = 0; i < 4; i++) | ||
307 | detailTexture[i].UnlockBits(datas[i]); | ||
308 | } | ||
309 | } | ||
310 | finally | ||
311 | { | ||
297 | for (int i = 0; i < 4; i++) | 312 | for (int i = 0; i < 4; i++) |
298 | detailTexture[i].UnlockBits(datas[i]); | 313 | if (detailTexture[i] != null) |
314 | detailTexture[i].Dispose(); | ||
299 | } | 315 | } |
300 | 316 | ||
301 | output.UnlockBits(outputData); | 317 | output.UnlockBits(outputData); |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index e6f2855..3c48d07 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | |||
@@ -54,8 +54,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
54 | private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); | 54 | private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); |
55 | private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); | 55 | private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); |
56 | 56 | ||
57 | private static readonly ILog m_log = | 57 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | 58 | ||
60 | private Scene m_scene; | 59 | private Scene m_scene; |
61 | private IRendering m_primMesher; | 60 | private IRendering m_primMesher; |
@@ -164,7 +163,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
164 | } | 163 | } |
165 | catch | 164 | catch |
166 | { | 165 | { |
167 | m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); | 166 | m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig"); |
168 | } | 167 | } |
169 | 168 | ||
170 | m_colors.Clear(); | 169 | m_colors.Clear(); |
@@ -218,7 +217,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
218 | Bitmap bitmap = renderer.Scene.getImage(); | 217 | Bitmap bitmap = renderer.Scene.getImage(); |
219 | 218 | ||
220 | if (m_useAntiAliasing) | 219 | if (m_useAntiAliasing) |
221 | bitmap = ImageUtils.ResizeImage(bitmap, viewport.Width, viewport.Height); | 220 | { |
221 | using (Bitmap origBitmap = bitmap) | ||
222 | bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); | ||
223 | } | ||
222 | 224 | ||
223 | return bitmap; | 225 | return bitmap; |
224 | } | 226 | } |
@@ -233,7 +235,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
233 | catch (Exception e) | 235 | catch (Exception e) |
234 | { | 236 | { |
235 | // JPEG2000 encoder failed | 237 | // JPEG2000 encoder failed |
236 | m_log.Error("[MAPTILE]: Failed generating terrain map: " + e); | 238 | m_log.Error("[WARP 3D IMAGE MODULE]: Failed generating terrain map: ", e); |
237 | } | 239 | } |
238 | 240 | ||
239 | return null; | 241 | return null; |
@@ -332,8 +334,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
332 | uint globalX, globalY; | 334 | uint globalX, globalY; |
333 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); | 335 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); |
334 | 336 | ||
335 | Bitmap image = TerrainSplat.Splat(heightmap, textureIDs, startHeights, heightRanges, new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain); | 337 | warp_Texture texture; |
336 | warp_Texture texture = new warp_Texture(image); | 338 | |
339 | using ( | ||
340 | Bitmap image | ||
341 | = TerrainSplat.Splat( | ||
342 | heightmap, textureIDs, startHeights, heightRanges, | ||
343 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) | ||
344 | { | ||
345 | texture = new warp_Texture(image); | ||
346 | } | ||
347 | |||
337 | warp_Material material = new warp_Material(texture); | 348 | warp_Material material = new warp_Material(texture); |
338 | material.setReflectivity(50); | 349 | material.setReflectivity(50); |
339 | renderer.Scene.addMaterial("TerrainColor", material); | 350 | renderer.Scene.addMaterial("TerrainColor", material); |
@@ -560,42 +571,46 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
560 | { | 571 | { |
561 | try | 572 | try |
562 | { | 573 | { |
563 | Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream); | 574 | int pixelBytes; |
564 | width = bitmap.Width; | ||
565 | height = bitmap.Height; | ||
566 | 575 | ||
567 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); | 576 | using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) |
568 | int pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; | ||
569 | |||
570 | // Sum up the individual channels | ||
571 | unsafe | ||
572 | { | 577 | { |
573 | if (pixelBytes == 4) | 578 | width = bitmap.Width; |
579 | height = bitmap.Height; | ||
580 | |||
581 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); | ||
582 | pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; | ||
583 | |||
584 | // Sum up the individual channels | ||
585 | unsafe | ||
574 | { | 586 | { |
575 | for (int y = 0; y < height; y++) | 587 | if (pixelBytes == 4) |
576 | { | 588 | { |
577 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 589 | for (int y = 0; y < height; y++) |
578 | |||
579 | for (int x = 0; x < width; x++) | ||
580 | { | 590 | { |
581 | b += row[x * pixelBytes + 0]; | 591 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
582 | g += row[x * pixelBytes + 1]; | 592 | |
583 | r += row[x * pixelBytes + 2]; | 593 | for (int x = 0; x < width; x++) |
584 | a += row[x * pixelBytes + 3]; | 594 | { |
595 | b += row[x * pixelBytes + 0]; | ||
596 | g += row[x * pixelBytes + 1]; | ||
597 | r += row[x * pixelBytes + 2]; | ||
598 | a += row[x * pixelBytes + 3]; | ||
599 | } | ||
585 | } | 600 | } |
586 | } | 601 | } |
587 | } | 602 | else |
588 | else | ||
589 | { | ||
590 | for (int y = 0; y < height; y++) | ||
591 | { | 603 | { |
592 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 604 | for (int y = 0; y < height; y++) |
593 | |||
594 | for (int x = 0; x < width; x++) | ||
595 | { | 605 | { |
596 | b += row[x * pixelBytes + 0]; | 606 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
597 | g += row[x * pixelBytes + 1]; | 607 | |
598 | r += row[x * pixelBytes + 2]; | 608 | for (int x = 0; x < width; x++) |
609 | { | ||
610 | b += row[x * pixelBytes + 0]; | ||
611 | g += row[x * pixelBytes + 1]; | ||
612 | r += row[x * pixelBytes + 2]; | ||
613 | } | ||
599 | } | 614 | } |
600 | } | 615 | } |
601 | } | 616 | } |
@@ -617,7 +632,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
617 | } | 632 | } |
618 | catch (Exception ex) | 633 | catch (Exception ex) |
619 | { | 634 | { |
620 | m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message); | 635 | m_log.WarnFormat( |
636 | "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", | ||
637 | textureID, j2kData.Length, ex.Message); | ||
638 | |||
621 | width = 0; | 639 | width = 0; |
622 | height = 0; | 640 | height = 0; |
623 | return new Color4(0.5f, 0.5f, 0.5f, 1.0f); | 641 | return new Color4(0.5f, 0.5f, 0.5f, 1.0f); |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index be6b240..724bb4c 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -1343,14 +1343,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1343 | if (terrain == null) | 1343 | if (terrain == null) |
1344 | return; | 1344 | return; |
1345 | 1345 | ||
1346 | m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); | ||
1347 | |||
1346 | byte[] data = terrain.WriteJpeg2000Image(); | 1348 | byte[] data = terrain.WriteJpeg2000Image(); |
1347 | if (data == null) | 1349 | if (data == null) |
1348 | return; | 1350 | return; |
1349 | 1351 | ||
1350 | byte[] overlay = GenerateOverlay(); | 1352 | byte[] overlay = GenerateOverlay(); |
1351 | 1353 | ||
1352 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); | ||
1353 | |||
1354 | UUID terrainImageID = UUID.Random(); | 1354 | UUID terrainImageID = UUID.Random(); |
1355 | UUID parcelImageID = UUID.Zero; | 1355 | UUID parcelImageID = UUID.Zero; |
1356 | 1356 | ||
@@ -1365,7 +1365,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1365 | asset.Flags = AssetFlags.Maptile; | 1365 | asset.Flags = AssetFlags.Maptile; |
1366 | 1366 | ||
1367 | // Store the new one | 1367 | // Store the new one |
1368 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); | 1368 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName); |
1369 | |||
1369 | m_scene.AssetService.Store(asset); | 1370 | m_scene.AssetService.Store(asset); |
1370 | 1371 | ||
1371 | if (overlay != null) | 1372 | if (overlay != null) |