From 2e15ed80cd642c33314cfd890cf06e0024c24102 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Wed, 19 Aug 2015 12:08:45 +0100
Subject: fixes on warp3D

---
 .../CoreModules/World/Warp3DMap/TerrainSplat.cs    | 37 +++++++++---
 .../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;
 using log4net;
 using OpenMetaverse;
 using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
 using OpenSim.Services.Interfaces;
 
 namespace OpenSim.Region.CoreModules.World.Warp3DMap
@@ -66,6 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         #endregion Constants
 
         private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+        private static string LogHeader = "[WARP3D TERRAIN SPLAT]";
 
         /// <summary>
         /// Builds a composited terrain texture given the region texture
@@ -76,9 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         /// <returns>A composited 256x256 RGB texture ready for rendering</returns>
         /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting
         /// </remarks>
-        public static Bitmap Splat(float[] heightmap, UUID[] textureIDs, float[] startHeights, float[] heightRanges, Vector3d regionPosition, IAssetService assetService, bool textureTerrain)
+        public static Bitmap Splat(ITerrainChannel terrain, UUID[] textureIDs, float[] startHeights, float[] heightRanges, Vector3d regionPosition, IAssetService assetService, bool textureTerrain)
         {
-            Debug.Assert(heightmap.Length == 256 * 256);
             Debug.Assert(textureIDs.Length == 4);
             Debug.Assert(startHeights.Length == 4);
             Debug.Assert(heightRanges.Length == 4);
@@ -200,17 +201,27 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                                 gfx.FillRectangle(brush, 0, 0, 256, 256);
                         }
                     }
+                    else
+                    {
+                        if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
+                        {
+                            detailTexture[i] = ResizeBitmap(detailTexture[i], 256, 256);
+                        }
+                    }
                 }
     
                 #region Layer Map
     
-                float[] layermap = new float[256 * 256];
+                float[,] layermap = new float[256 , 256];
+
+                int xFactor = terrain.Width / 256;
+                int yFactor = terrain.Height / 256;
     
                 for (int y = 0; y < 256; y++)
                 {
                     for (int x = 0; x < 256; x++)
                     {
-                        float height = heightmap[y * 256 + x];
+                        float height = (float)terrain[x * xFactor, y * yFactor];
     
                         float pctX = (float)x / 255f;
                         float pctY = (float)y / 255f;
@@ -237,8 +248,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                         // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting
                         Vector3 vec = new Vector3
                         (
-                            ((float)regionPosition.X + x) * 0.20319f,
-                            ((float)regionPosition.Y + y) * 0.20319f,
+                            ((float)regionPosition.X + (x * xFactor)) * 0.20319f,
+                            ((float)regionPosition.Y + (y * yFactor)) * 0.20319f,
                             height * 0.25f
                         );
     
@@ -249,7 +260,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                         // Combine the current height, generated noise, start height, and height range parameters, then scale all of it 
                         float layer = ((height + noise - startHeight) / heightRange) * 4f;
                         if (Single.IsNaN(layer)) layer = 0f;
-                        layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f);
+                        layermap[x,y] = Utils.Clamp(layer, 0f, 3f);
                     }
                 }
     
@@ -283,7 +294,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                     {
                         for (int x = 0; x < 256; x++)
                         {
-                            float layer = layermap[y * 256 + x];
+                            float layer = layermap[x, y];
     
                             // Select two textures
                             int l0 = (int)Math.Floor(layer);
@@ -331,6 +342,16 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
             return output;
         }
 
+        public static Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
+        {
+            m_log.DebugFormat("{0} ResizeBitmap. From <{1},{2}> to <{3},{4}>",
+                                LogHeader, b.Width, b.Height, nWidth, nHeight);
+            Bitmap result = new Bitmap(nWidth, nHeight);
+            using (Graphics g = Graphics.FromImage(result))
+                g.DrawImage(b, 0, 0, nWidth, nHeight);
+            b.Dispose();
+            return result;
+        }
         public static Bitmap SplatSimple(float[] heightmap)
         {
             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
                 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
             }
 
-            Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f);
-            Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize);
+            Vector3 camPos = new Vector3(
+                            m_scene.RegionInfo.RegionSizeX / 2 - 0.5f,
+                            m_scene.RegionInfo.RegionSizeY / 2 - 0.5f,
+                            221.7025033688163f);
+            // Viewport viewing down onto the region
+            Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f,
+                        (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY,
+                        (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY);
+
             Bitmap tile = CreateMapTile(viewport, false);
             m_primMesher = null;
 
@@ -254,8 +261,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         {
             float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;
 
-            renderer.AddPlane("Water", 256f * 0.5f);
-            renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f);
+            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
+            renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX / 2 - 0.5f,
+                                                       waterHeight,
+                                                       m_scene.RegionInfo.RegionSizeY / 2 - 0.5f);
 
             renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR));
 			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
         private void CreateTerrain(WarpRenderer renderer, bool textureTerrain)
         {
             ITerrainChannel terrain = m_scene.Heightmap;
-            float[] heightmap = terrain.GetFloatsSerialised();
+
+            // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding
+            float diff = (float)m_scene.RegionInfo.RegionSizeX / 256f;
 
             warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2);
 
-            for (int y = 0; y < 256; y++)
+            // Create all the vertices for the terrain
+            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
             {
-                for (int x = 0; x < 256; x++)
+                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                 {
-                    int v = y * 256 + x;
-                    float height = heightmap[v];
-
-                    warp_Vector pos = ConvertVector(new Vector3(x, y, height));
-                    obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f));
+                    warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]);
+                    obj.addVertex(new warp_Vertex(pos,
+                        x / (float)m_scene.RegionInfo.RegionSizeX,
+                        (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY));
                 }
             }
 
-            for (int y = 0; y < 256; y++)
+            // Now that we have all the vertices, make another pass and create
+            //     the normals for each of the surface triangles and
+            //     create the list of triangle indices.
+            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
             {
-                for (int x = 0; x < 256; x++)
+                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                 {
-                    if (x < 255 && y < 255)
+                    float newX = x / diff;
+                    float newY = y / diff;
+                    if (newX < 255 && newY < 255)
                     {
-                        int v = y * 256 + x;
+                        int v = (int)newY * 256 + (int)newX;
 
-                        // Normal
-                        Vector3 v1 = new Vector3(x, y, heightmap[y * 256 + x]);
-                        Vector3 v2 = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]);
-                        Vector3 v3 = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]);
+                        // Normal for a triangle made up of three adjacent vertices
+                        Vector3 v1 = new Vector3(newX, newY, (float)terrain[(int)x, (int)y]);
+                        Vector3 v2 = new Vector3(newX + 1, newY, (float)terrain[(int)(x + 1), (int)y]);
+                        Vector3 v3 = new Vector3(newX, newY + 1, (float)terrain[(int)x, ((int)(y + 1))]);
                         warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                         norm = norm.reverse();
                         obj.vertex(v).n = norm;
 
-                        // Triangle 1
+                        // Make two triangles for each of the squares in the grid of vertices
                         obj.addTriangle(
                             v,
                             v + 1,
                             v + 256);
 
-                        // Triangle 2
                         obj.addTriangle(
                             v + 256 + 1,
                             v + 256,
@@ -337,14 +352,14 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
             heightRanges[3] = (float)regionInfo.Elevation2NE;
 
             uint globalX, globalY;
-            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);
+            Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);
 
             warp_Texture texture;
 
             using (
                 Bitmap image
                     = TerrainSplat.Splat(
-                        heightmap, textureIDs, startHeights, heightRanges,
+                        terrain, textureIDs, startHeights, heightRanges,
                         new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
             {
                 texture = new warp_Texture(image);
@@ -534,6 +549,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         #endregion Rendering Methods
 
         #region Static Helpers
+        // Note: axis change.
+        private static warp_Vector ConvertVector(float x, float y, float z)
+        {
+            return new warp_Vector(x, z, y);
+        }
 
         private static warp_Vector ConvertVector(Vector3 vector)
         {
-- 
cgit v1.1