diff options
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | 37 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | 68 |
2 files changed, 73 insertions, 32 deletions
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index df5ac92..91ca7e2 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | |||
@@ -32,6 +32,7 @@ using System.Drawing.Imaging; | |||
32 | using log4net; | 32 | using log4net; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Framework.Interfaces; | ||
35 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.World.Warp3DMap | 38 | namespace OpenSim.Region.CoreModules.World.Warp3DMap |
@@ -66,6 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
66 | #endregion Constants | 67 | #endregion Constants |
67 | 68 | ||
68 | private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); | 69 | private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); |
70 | private static string LogHeader = "[WARP3D TERRAIN SPLAT]"; | ||
69 | 71 | ||
70 | /// <summary> | 72 | /// <summary> |
71 | /// Builds a composited terrain texture given the region texture | 73 | /// Builds a composited terrain texture given the region texture |
@@ -76,9 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
76 | /// <returns>A composited 256x256 RGB texture ready for rendering</returns> | 78 | /// <returns>A composited 256x256 RGB texture ready for rendering</returns> |
77 | /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting | 79 | /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting |
78 | /// </remarks> | 80 | /// </remarks> |
79 | public static Bitmap Splat(float[] heightmap, UUID[] textureIDs, float[] startHeights, float[] heightRanges, Vector3d regionPosition, IAssetService assetService, bool textureTerrain) | 81 | public static Bitmap Splat(ITerrainChannel terrain, UUID[] textureIDs, float[] startHeights, float[] heightRanges, Vector3d regionPosition, IAssetService assetService, bool textureTerrain) |
80 | { | 82 | { |
81 | Debug.Assert(heightmap.Length == 256 * 256); | ||
82 | Debug.Assert(textureIDs.Length == 4); | 83 | Debug.Assert(textureIDs.Length == 4); |
83 | Debug.Assert(startHeights.Length == 4); | 84 | Debug.Assert(startHeights.Length == 4); |
84 | Debug.Assert(heightRanges.Length == 4); | 85 | Debug.Assert(heightRanges.Length == 4); |
@@ -200,17 +201,27 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
200 | gfx.FillRectangle(brush, 0, 0, 256, 256); | 201 | gfx.FillRectangle(brush, 0, 0, 256, 256); |
201 | } | 202 | } |
202 | } | 203 | } |
204 | else | ||
205 | { | ||
206 | if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) | ||
207 | { | ||
208 | detailTexture[i] = ResizeBitmap(detailTexture[i], 256, 256); | ||
209 | } | ||
210 | } | ||
203 | } | 211 | } |
204 | 212 | ||
205 | #region Layer Map | 213 | #region Layer Map |
206 | 214 | ||
207 | float[] layermap = new float[256 * 256]; | 215 | float[,] layermap = new float[256 , 256]; |
216 | |||
217 | int xFactor = terrain.Width / 256; | ||
218 | int yFactor = terrain.Height / 256; | ||
208 | 219 | ||
209 | for (int y = 0; y < 256; y++) | 220 | for (int y = 0; y < 256; y++) |
210 | { | 221 | { |
211 | for (int x = 0; x < 256; x++) | 222 | for (int x = 0; x < 256; x++) |
212 | { | 223 | { |
213 | float height = heightmap[y * 256 + x]; | 224 | float height = (float)terrain[x * xFactor, y * yFactor]; |
214 | 225 | ||
215 | float pctX = (float)x / 255f; | 226 | float pctX = (float)x / 255f; |
216 | float pctY = (float)y / 255f; | 227 | float pctY = (float)y / 255f; |
@@ -237,8 +248,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
237 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting | 248 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting |
238 | Vector3 vec = new Vector3 | 249 | Vector3 vec = new Vector3 |
239 | ( | 250 | ( |
240 | ((float)regionPosition.X + x) * 0.20319f, | 251 | ((float)regionPosition.X + (x * xFactor)) * 0.20319f, |
241 | ((float)regionPosition.Y + y) * 0.20319f, | 252 | ((float)regionPosition.Y + (y * yFactor)) * 0.20319f, |
242 | height * 0.25f | 253 | height * 0.25f |
243 | ); | 254 | ); |
244 | 255 | ||
@@ -249,7 +260,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
249 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it | 260 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it |
250 | float layer = ((height + noise - startHeight) / heightRange) * 4f; | 261 | float layer = ((height + noise - startHeight) / heightRange) * 4f; |
251 | if (Single.IsNaN(layer)) layer = 0f; | 262 | if (Single.IsNaN(layer)) layer = 0f; |
252 | layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); | 263 | layermap[x,y] = Utils.Clamp(layer, 0f, 3f); |
253 | } | 264 | } |
254 | } | 265 | } |
255 | 266 | ||
@@ -283,7 +294,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
283 | { | 294 | { |
284 | for (int x = 0; x < 256; x++) | 295 | for (int x = 0; x < 256; x++) |
285 | { | 296 | { |
286 | float layer = layermap[y * 256 + x]; | 297 | float layer = layermap[x, y]; |
287 | 298 | ||
288 | // Select two textures | 299 | // Select two textures |
289 | int l0 = (int)Math.Floor(layer); | 300 | int l0 = (int)Math.Floor(layer); |
@@ -331,6 +342,16 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
331 | return output; | 342 | return output; |
332 | } | 343 | } |
333 | 344 | ||
345 | public static Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight) | ||
346 | { | ||
347 | m_log.DebugFormat("{0} ResizeBitmap. From <{1},{2}> to <{3},{4}>", | ||
348 | LogHeader, b.Width, b.Height, nWidth, nHeight); | ||
349 | Bitmap result = new Bitmap(nWidth, nHeight); | ||
350 | using (Graphics g = Graphics.FromImage(result)) | ||
351 | g.DrawImage(b, 0, 0, nWidth, nHeight); | ||
352 | b.Dispose(); | ||
353 | return result; | ||
354 | } | ||
334 | public static Bitmap SplatSimple(float[] heightmap) | 355 | public static Bitmap SplatSimple(float[] heightmap) |
335 | { | 356 | { |
336 | const float BASE_HSV_H = 93f / 360f; | 357 | const float BASE_HSV_H = 93f / 360f; |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index d38f34b..17066bd 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | |||
@@ -136,8 +136,15 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
136 | m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); | 136 | m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); |
137 | } | 137 | } |
138 | 138 | ||
139 | Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); | 139 | Vector3 camPos = new Vector3( |
140 | Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); | 140 | m_scene.RegionInfo.RegionSizeX / 2 - 0.5f, |
141 | m_scene.RegionInfo.RegionSizeY / 2 - 0.5f, | ||
142 | 221.7025033688163f); | ||
143 | // Viewport viewing down onto the region | ||
144 | Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, | ||
145 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, | ||
146 | (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY); | ||
147 | |||
141 | Bitmap tile = CreateMapTile(viewport, false); | 148 | Bitmap tile = CreateMapTile(viewport, false); |
142 | m_primMesher = null; | 149 | m_primMesher = null; |
143 | 150 | ||
@@ -254,8 +261,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
254 | { | 261 | { |
255 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; | 262 | float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; |
256 | 263 | ||
257 | renderer.AddPlane("Water", 256f * 0.5f); | 264 | renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f); |
258 | renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); | 265 | renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX / 2 - 0.5f, |
266 | waterHeight, | ||
267 | m_scene.RegionInfo.RegionSizeY / 2 - 0.5f); | ||
259 | 268 | ||
260 | renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); | 269 | renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); |
261 | renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif | 270 | renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif |
@@ -266,45 +275,51 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
266 | private void CreateTerrain(WarpRenderer renderer, bool textureTerrain) | 275 | private void CreateTerrain(WarpRenderer renderer, bool textureTerrain) |
267 | { | 276 | { |
268 | ITerrainChannel terrain = m_scene.Heightmap; | 277 | ITerrainChannel terrain = m_scene.Heightmap; |
269 | float[] heightmap = terrain.GetFloatsSerialised(); | 278 | |
279 | // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding | ||
280 | float diff = (float)m_scene.RegionInfo.RegionSizeX / 256f; | ||
270 | 281 | ||
271 | warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2); | 282 | warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2); |
272 | 283 | ||
273 | for (int y = 0; y < 256; y++) | 284 | // Create all the vertices for the terrain |
285 | for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff) | ||
274 | { | 286 | { |
275 | for (int x = 0; x < 256; x++) | 287 | for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff) |
276 | { | 288 | { |
277 | int v = y * 256 + x; | 289 | warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]); |
278 | float height = heightmap[v]; | 290 | obj.addVertex(new warp_Vertex(pos, |
279 | 291 | x / (float)m_scene.RegionInfo.RegionSizeX, | |
280 | warp_Vector pos = ConvertVector(new Vector3(x, y, height)); | 292 | (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY)); |
281 | obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f)); | ||
282 | } | 293 | } |
283 | } | 294 | } |
284 | 295 | ||
285 | for (int y = 0; y < 256; y++) | 296 | // Now that we have all the vertices, make another pass and create |
297 | // the normals for each of the surface triangles and | ||
298 | // create the list of triangle indices. | ||
299 | for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff) | ||
286 | { | 300 | { |
287 | for (int x = 0; x < 256; x++) | 301 | for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff) |
288 | { | 302 | { |
289 | if (x < 255 && y < 255) | 303 | float newX = x / diff; |
304 | float newY = y / diff; | ||
305 | if (newX < 255 && newY < 255) | ||
290 | { | 306 | { |
291 | int v = y * 256 + x; | 307 | int v = (int)newY * 256 + (int)newX; |
292 | 308 | ||
293 | // Normal | 309 | // Normal for a triangle made up of three adjacent vertices |
294 | Vector3 v1 = new Vector3(x, y, heightmap[y * 256 + x]); | 310 | Vector3 v1 = new Vector3(newX, newY, (float)terrain[(int)x, (int)y]); |
295 | Vector3 v2 = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]); | 311 | Vector3 v2 = new Vector3(newX + 1, newY, (float)terrain[(int)(x + 1), (int)y]); |
296 | Vector3 v3 = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]); | 312 | Vector3 v3 = new Vector3(newX, newY + 1, (float)terrain[(int)x, ((int)(y + 1))]); |
297 | warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3)); | 313 | warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3)); |
298 | norm = norm.reverse(); | 314 | norm = norm.reverse(); |
299 | obj.vertex(v).n = norm; | 315 | obj.vertex(v).n = norm; |
300 | 316 | ||
301 | // Triangle 1 | 317 | // Make two triangles for each of the squares in the grid of vertices |
302 | obj.addTriangle( | 318 | obj.addTriangle( |
303 | v, | 319 | v, |
304 | v + 1, | 320 | v + 1, |
305 | v + 256); | 321 | v + 256); |
306 | 322 | ||
307 | // Triangle 2 | ||
308 | obj.addTriangle( | 323 | obj.addTriangle( |
309 | v + 256 + 1, | 324 | v + 256 + 1, |
310 | v + 256, | 325 | v + 256, |
@@ -337,14 +352,14 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
337 | heightRanges[3] = (float)regionInfo.Elevation2NE; | 352 | heightRanges[3] = (float)regionInfo.Elevation2NE; |
338 | 353 | ||
339 | uint globalX, globalY; | 354 | uint globalX, globalY; |
340 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); | 355 | Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); |
341 | 356 | ||
342 | warp_Texture texture; | 357 | warp_Texture texture; |
343 | 358 | ||
344 | using ( | 359 | using ( |
345 | Bitmap image | 360 | Bitmap image |
346 | = TerrainSplat.Splat( | 361 | = TerrainSplat.Splat( |
347 | heightmap, textureIDs, startHeights, heightRanges, | 362 | terrain, textureIDs, startHeights, heightRanges, |
348 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) | 363 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) |
349 | { | 364 | { |
350 | texture = new warp_Texture(image); | 365 | texture = new warp_Texture(image); |
@@ -534,6 +549,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
534 | #endregion Rendering Methods | 549 | #endregion Rendering Methods |
535 | 550 | ||
536 | #region Static Helpers | 551 | #region Static Helpers |
552 | // Note: axis change. | ||
553 | private static warp_Vector ConvertVector(float x, float y, float z) | ||
554 | { | ||
555 | return new warp_Vector(x, z, y); | ||
556 | } | ||
537 | 557 | ||
538 | private static warp_Vector ConvertVector(Vector3 vector) | 558 | private static warp_Vector ConvertVector(Vector3 vector) |
539 | { | 559 | { |