From 459a5d77ee6ceda20ff21798f6dc8dab37ba0b77 Mon Sep 17 00:00:00 2001
From: onefang
Date: Sun, 19 May 2019 22:31:34 +1000
Subject: Merge Warp3DCachedImageModule from Christopher Latza.

Plus some of my own tweaks.
Minus some of his.
---
 .../World/Warp3DMap/Warp3DImageModule.cs           | 225 ++++++++++++++++-----
 1 file changed, 180 insertions(+), 45 deletions(-)

diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 4934ebd..7b7cce8 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -41,8 +41,8 @@ using Mono.Addins;
 using OpenSim.Framework;
 using OpenSim.Region.Framework.Interfaces;
 using OpenSim.Region.Framework.Scenes;
-using OpenSim.Region.PhysicsModules.SharedBase;
-using OpenSim.Services.Interfaces;
+//using OpenSim.Region.PhysicsModules.SharedBase;
+//using OpenSim.Services.Interfaces;
 
 using OpenMetaverse;
 using OpenMetaverse.Assets;
@@ -51,6 +51,7 @@ using OpenMetaverse.Rendering;
 using OpenMetaverse.StructuredData;
 
 using WarpRenderer = global::Warp3D.Warp3D;
+using System.Drawing.Drawing2D;
 
 namespace OpenSim.Region.CoreModules.World.Warp3DMap
 {
@@ -76,10 +77,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         private bool m_texturePrims = true;     // true if should texture the rendered prims
         private float m_texturePrimSize = 48f;  // size of prim before we consider texturing it
         private bool m_renderMeshes = false;    // true if to render meshes rather than just bounding boxes
-
+        private String m_cacheDirectory = "";
         private bool m_Enabled = false;
 
-//        private Bitmap lastImage = null;
+//        private bool m_enable_date = false;
+//        private bool m_enable_regionName = false;
+        private bool m_enable_regionPosition = false;
+        private bool m_enable_refreshEveryMonth = false;
+//        private bool m_enable_HostedBy = false;
+//        private String m_enable_HostedByText = "";
+
+        //        private Bitmap lastImage = null;
         private DateTime lastImageTime = DateTime.MinValue;
 
         #region Region Module interface
@@ -106,7 +114,20 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                 = Util.GetConfigVarFromSections<float>(m_config, "TexturePrimSize", configSections, m_texturePrimSize);
             m_renderMeshes
                 = Util.GetConfigVarFromSections<bool>(m_config, "RenderMeshes", configSections, m_renderMeshes);
-         }
+            m_cacheDirectory
+                = Util.GetConfigVarFromSections<string>(m_config, "CacheDirectory", configSections, System.IO.Path.Combine(Util.cacheDir(), "MapImageCache"));
+
+
+//            m_enable_date = Util.GetConfigVarFromSections<bool>(m_config, "enableDate", configSections, false);
+//            m_enable_regionName = Util.GetConfigVarFromSections<bool>(m_config, "enableName", configSections, false);
+            m_enable_regionPosition = Util.GetConfigVarFromSections<bool>(m_config, "enablePosition", configSections, false);
+            m_enable_refreshEveryMonth = Util.GetConfigVarFromSections<bool>(m_config, "RefreshEveryMonth", configSections, true);
+//            m_enable_HostedBy = Util.GetConfigVarFromSections<bool>(m_config, "enableHostedBy", configSections, false);
+//            m_enable_HostedByText = Util.GetConfigVarFromSections<String>(m_config, "HosterText", configSections, String.Empty);
+
+            if (!Directory.Exists(m_cacheDirectory))
+                Directory.CreateDirectory(m_cacheDirectory);
+        }
 
         public void AddRegion(Scene scene)
         {
@@ -149,39 +170,138 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         #endregion
 
         #region IMapImageGenerator Members
-
-        public Bitmap CreateMapTile()
+/*
+        public static string fillInt(int _i, int _l)
         {
-            /* this must be on all map, not just its image
-            if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
+            String _return = _i.ToString();
+
+            while(_return.Length < _l)
             {
-                return (Bitmap)lastImage.Clone();
+                _return = 0 + _return;
             }
-            */
 
-            List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
-            if (renderers.Count > 0)
+            return _return;
+        }
+
+        public static int getCurrentUnixTime()
+        {
+            return (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
+        }
+
+        public static String unixTimeToDateString(int unixTime)
+        {
+            DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
+            long unixTimeStampInTicks = (long)(unixTime * TimeSpan.TicksPerSecond);
+            DateTime _date = new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc);
+
+            return fillInt(_date.Day, 2) + "." + fillInt(_date.Month, 2) + "." + fillInt(_date.Year, 4) + " " + fillInt(_date.Hour, 2) + ":" + fillInt(_date.Minute, 2);
+        }
+
+        private void writeDateOnMap(ref Bitmap _map)
+        {
+            RectangleF rectf = new RectangleF(2, 1, 200, 25);
+
+            Graphics g = Graphics.FromImage(_map);
+            g.SmoothingMode = SmoothingMode.AntiAlias;
+            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
+            g.DrawString(unixTimeToDateString(getCurrentUnixTime()), new Font("Arial", 8), Brushes.White, rectf);
+            g.Flush();
+        }
+
+        private void writeNameOnMap(ref Bitmap _map)
+        {
+            RectangleF rectf = new RectangleF(2, m_scene.RegionInfo.RegionSizeX - 15, 200, 25);
+
+            Graphics g = Graphics.FromImage(_map);
+            g.SmoothingMode = SmoothingMode.AntiAlias;
+            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
+            g.DrawString(m_scene.Name, new Font("Arial", 8), Brushes.White, rectf);
+            g.Flush();
+        }
+*/
+        private void writePositionOnMap(ref Bitmap _map)
+        {
+            RectangleF rectf = new RectangleF(m_scene.RegionInfo.RegionSizeY - 75, m_scene.RegionInfo.RegionSizeX - 15, 80, 25);
+
+            Graphics g = Graphics.FromImage(_map);
+            g.SmoothingMode = SmoothingMode.AntiAlias;
+            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
+            g.DrawString("<" + m_scene.RegionInfo.RegionLocX + " " + m_scene.RegionInfo.RegionLocY + ">", new Font("Arial", 8), Brushes.White, rectf);
+            g.Flush();
+        }
+/*
+        private void writeHostedByOnMap(ref Bitmap _map)
+        {
+            RectangleF rectf = new RectangleF(2, m_scene.RegionInfo.RegionSizeX - 15, 200, 25);
+
+            Graphics g = Graphics.FromImage(_map);
+            g.SmoothingMode = SmoothingMode.AntiAlias;
+            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
+            g.DrawString(m_enable_HostedByText, new Font("Arial", 8), Brushes.Gray, rectf);
+            g.Flush();
+        }
+*/
+        public Bitmap CreateMapTile()
+        {
+            if ((File.GetCreationTime(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")).Month != DateTime.Now.Month) && m_enable_refreshEveryMonth == true)
+                File.Delete(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp"));
+
+            if(File.Exists(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp")))
             {
-                m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
+                return new Bitmap(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp"));
             }
+            else
+            {
+                /* this must be on all map, not just its image
+                if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
+                {
+                    return (Bitmap)lastImage.Clone();
+                }
+                */
 
-            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;
-            return tile;
-/*
-            lastImage = tile;
-            lastImageTime = DateTime.Now;
-            return (Bitmap)lastImage.Clone();
- */
+                List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
+                if (renderers.Count > 0)
+                {
+                    m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
+                }
+
+                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);
+
+//                if (m_enable_date)
+//                    writeDateOnMap(ref tile);
+
+//                if (m_enable_regionName)
+//                    writeNameOnMap(ref tile);
+
+                if (m_enable_regionPosition)
+                    writePositionOnMap(ref tile);
+
+//                if (m_enable_HostedBy)
+//                    writeHostedByOnMap(ref tile);
+
+                tile.Save(System.IO.Path.Combine(m_cacheDirectory, m_scene.RegionInfo.RegionID + ".bmp"));
+                m_primMesher = null;
+                return tile;
+
+                /*
+                            lastImage = tile;
+                            lastImageTime = DateTime.Now;
+                            return (Bitmap)lastImage.Clone();
+                 */
+            }
         }
 
         public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures)
@@ -271,16 +391,20 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
         {
             float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;
 
-            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
-            renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX * 0.5f - 0.5f,
-                                                       waterHeight,
-                                                       m_scene.RegionInfo.RegionSizeY * 0.5f - 0.5f);
-
             warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR));
             waterColorMaterial.setReflectivity(0);  // match water color with standard map module thanks lkalif
             waterColorMaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
             renderer.Scene.addMaterial("WaterColor", waterColorMaterial);
-            renderer.SetObjectMaterial("Water", "WaterColor");
+
+            for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / 256; x++)
+            {
+                for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / 256; y++)
+                {
+                    renderer.AddPlane("Water-" + x + "-" + y, 256);
+                    renderer.Scene.sceneobject("Water-" + x + "-" + y).setPos(256 * x, waterHeight, 256 * y);
+                    renderer.SetObjectMaterial("Water-" + x + "-" + y, "WaterColor");
+                }
+            }
         }
 
         // Add a terrain to the renderer.
@@ -428,14 +552,25 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                         else // It's sculptie
                         {
                             IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
-                            if(imgDecoder != null)
+                            if (imgDecoder != null)
                             {
-                                Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
-                                if(sculpt != null)
+                                try
+                                {
+                                    Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
+                                    if (sculpt != null)
+                                    {
+                                        renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
+                                                                                        DetailLevel.Medium);
+                                        sculpt.Dispose();
+                                    }
+                                }
+                                catch (Exception e)
                                 {
-                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim,(Bitmap)sculpt,
-                                                                                            DetailLevel.Medium);
-                                    sculpt.Dispose();
+                                    Vector3 objectPos = prim.ParentGroup.RootPart.AbsolutePosition;
+//// TODO - print out owner of SceneObjectPart prim.
+                                    m_log.Error(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0} @ {1},{2},{3} - {4}.",
+                                        omvPrim.Sculpt.SculptTexture, objectPos.X, objectPos.Y, objectPos.Z, 
+                                        prim.ParentGroup.RootPart.Name));
                                 }
                             }
                         }
@@ -615,7 +750,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                 }
                 catch (Exception e)
                 {
-                    m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception  ", id), e);
+                    m_log.Debug(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception  ", id));
                 }
             }
 
@@ -733,7 +868,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
                 }
                 catch (Exception ex)
                 {
-                    m_log.WarnFormat(
+                    m_log.DebugFormat(
                         "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}",
                         textureID, j2kData.Length, ex.Message);
 
-- 
cgit v1.1