Beispiel #1
0
        ///<summary>
        ///
        ///</summary>
        public void UploadMapTile(IScene scene)
        {
            m_log.DebugFormat("{0}: upload maptile for {1}", LogHeader, scene.RegionInfo.RegionName);

            // Create a JPG map tile and upload it to the AddMapTile API
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.WarnFormat("{0} Cannot upload map tile without an ImageGenerator", LogHeader);
                return;
            }

            using (Bitmap mapTile = tileGenerator.CreateMapTile())
            {
                // XXX: The MapImageModule will return a null if the user has chosen not to create map tiles and there
                // is no static map tile.
                if (mapTile == null)
                {
                    return;
                }

                UploadMapTile(scene, mapTile);
            }
        }
        ///<summary>
        ///
        ///</summary>
        private void UploadMapTile(IScene scene)
        {
            m_log.DebugFormat("{0} Upload maptile for {1}", LogHeader, scene.RegionInfo.RegionName);
            string regionName = scene.RegionInfo.RegionName;

            // Create a JPG map tile and upload it to the AddMapTile API
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.WarnFormat("{0} Cannot upload map tile without an ImageGenerator", LogHeader);
                return;
            }
            using (Bitmap mapTile = tileGenerator.CreateMapTile())
            {
                if (mapTile != null)
                {
                    // mapTile.Save(   // DEBUG DEBUG
                    //     String.Format("maptiles/raw-{0}-{1}-{2}.jpg", regionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY),
                    //     ImageFormat.Jpeg);
                    // If the region/maptile is legacy sized, just upload the one tile like it has always been done
                    if (mapTile.Width == Constants.RegionSize && mapTile.Height == Constants.RegionSize)
                    {
                        ConvertAndUploadMaptile(mapTile,
                                                scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY,
                                                scene.RegionInfo.RegionName);
                    }
                    else
                    {
                        // For larger regions (varregion) we must cut the region image into legacy sized
                        //    pieces since that is how the maptile system works.
                        // Note the assumption that varregions are always a multiple of legacy size.
                        for (uint xx = 0; xx < mapTile.Width; xx += Constants.RegionSize)
                        {
                            for (uint yy = 0; yy < mapTile.Height; yy += Constants.RegionSize)
                            {
                                // Images are addressed from the upper left corner so have to do funny
                                //     math to pick out the sub-tile since regions are numbered from
                                //     the lower left.
                                Rectangle rect = new Rectangle(
                                    (int)xx,
                                    mapTile.Height - (int)yy - (int)Constants.RegionSize,
                                    (int)Constants.RegionSize, (int)Constants.RegionSize);
                                using (Bitmap subMapTile = mapTile.Clone(rect, mapTile.PixelFormat))
                                {
                                    ConvertAndUploadMaptile(subMapTile,
                                                            scene.RegionInfo.RegionLocX + (xx / Constants.RegionSize),
                                                            scene.RegionInfo.RegionLocY + (yy / Constants.RegionSize),
                                                            regionName);
                                }
                            }
                        }
                    }
                }
                else
                {
                    m_log.WarnFormat("{0} Tile image generation failed", LogHeader);
                }
            }
        }
Beispiel #3
0
        public void CreateMapTileAsync(AssetBase Mapasset, AssetBase Terrainasset, UUID lastMapRegionUUID, UUID lastTerrainRegionUUID)
        {
            IMapImageGenerator terrain = m_scene.RequestModuleInterface <IMapImageGenerator>();

            if (terrain == null)
            {
                return;
            }

            //Delete the old assets
            if (lastMapRegionUUID != UUID.Zero)
            {
                m_scene.AssetService.Delete(lastMapRegionUUID.ToString());
            }
            if (lastTerrainRegionUUID != UUID.Zero)
            {
                m_scene.AssetService.Delete(lastTerrainRegionUUID.ToString());
            }

            byte[] terraindata, mapdata;
            terrain.CreateMapTile(out terraindata, out mapdata);
            if (terraindata != null)
            {
                Terrainasset.Data = terraindata;
                m_scene.AssetService.Store(Terrainasset);
            }

            if (mapdata != null)
            {
                Mapasset.Data = mapdata;
                m_scene.AssetService.Store(Mapasset);
                RegenerateMaptile(Mapasset.ID, Mapasset.Data);
            }
            else if (Terrainasset != null)
            {
                RegenerateMaptile(Terrainasset.ID, Terrainasset.Data);
            }

            if (Terrainasset != null)
            {
                Terrainasset.Data = null;
                Terrainasset      = null;
            }
            if (Mapasset != null)
            {
                Mapasset.Data = null;
                Mapasset      = null;
            }

            //Update the grid map
            IGridRegisterModule gridRegModule = m_scene.RequestModuleInterface <IGridRegisterModule>();

            if (gridRegModule != null)
            {
                gridRegModule.UpdateGridRegion(m_scene);
            }
        }
Beispiel #4
0
        ///<summary>
        ///
        ///</summary>
        private void UploadMapTile(IScene scene)
        {
            m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName);

            // Create a JPG map tile and upload it to the AddMapTile API
            byte[]             jpgData       = Utils.EmptyBytes;
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator");
                return;
            }

            using (Image mapTile = tileGenerator.CreateMapTile())
            {
                // XXX: The MapImageModule will return a null if the user has chosen not to create map tiles and there
                // is no static map tile.
                if (mapTile == null)
                {
                    return;
                }

                using (MemoryStream stream = new MemoryStream())
                {
                    mapTile.Save(stream, ImageFormat.Jpeg);
                    jpgData = stream.ToArray();
                }
            }

            if (jpgData == Utils.EmptyBytes)
            {
                m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Tile image generation failed");
                return;
            }

            string reason = string.Empty;

            if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason))
            {
                m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}",
                                  scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason);
            }
        }
        ///<summary>
        ///
        ///</summary>
        private void UploadMapTile(IScene scene)
        {
            // Create a JPG map tile and upload it to the AddMapTile API
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.WarnFormat("{0} Cannot upload map tile without an ImageGenerator", LogHeader);
                return;
            }

            using (Bitmap mapTile = tileGenerator.CreateMapTile())
            {
                if (mapTile != null)
                {
                    UploadMapTile(scene, mapTile);
                }
                else
                {
                    m_log.WarnFormat("{0} Tile image generation failed", LogHeader);
                }
            }
        }
        ///<summary>
        ///
        ///</summary>
        private void UploadMapTile(IScene scene)
        {
            m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}", scene.RegionInfo.RegionName);

            // Create a PNG map tile and upload it to the AddMapTile API
            byte[]             pngData       = Utils.EmptyBytes;
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.Warn("[SIMIAN MAPTILE]: Cannot upload PNG map tile without an ImageGenerator");
                return;
            }

            using (Image mapTile = tileGenerator.CreateMapTile())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    mapTile.Save(stream, ImageFormat.Png);
                    pngData = stream.ToArray();
                }
            }

            List <MultipartForm.Element> postParameters = new List <MultipartForm.Element>()
            {
                new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
                new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
                new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
            };

            string errorMessage = null;
            int    tickstart    = Util.EnvironmentTickCount();

            // Make the remote storage request
            try
            {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
                request.Timeout          = 20000;
                request.ReadWriteTimeout = 5000;

                using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        string responseStr = responseStream.GetStreamString();
                        OSD    responseOSD = OSDParser.Deserialize(responseStr);
                        if (responseOSD.Type == OSDType.Map)
                        {
                            OSDMap responseMap = (OSDMap)responseOSD;
                            if (responseMap["Success"].AsBoolean())
                            {
                                return;
                            }

                            errorMessage = "Upload failed: " + responseMap["Message"].AsString();
                        }
                        else
                        {
                            errorMessage = "Response format was invalid:\n" + responseStr;
                        }
                    }
                }
            }
            catch (WebException we)
            {
                errorMessage = we.Message;
                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse webResponse = (HttpWebResponse)we.Response;
                    errorMessage = String.Format("[{0}] {1}",
                                                 webResponse.StatusCode, webResponse.StatusDescription);
                }
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }
            finally
            {
                // This just dumps a warning for any operation that takes more than 100 ms
                int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
                m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms", tickdiff);
            }

            m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}",
                             pngData.Length, scene.RegionInfo.RegionName, errorMessage);
        }
Beispiel #7
0
        private void UploadMapTile(IScene scene)
        {
            string errorMessage = null;

            // Create a PNG map tile and upload it to the AddMapTile API
            byte[]             pngData       = Utils.EmptyBytes;
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.Warn("[SIMIAN GRID CONNECTOR]: Cannot upload PNG map tile without an IMapImageGenerator");
                return;
            }

            using (Image mapTile = tileGenerator.CreateMapTile("defaultstripe.png"))
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    mapTile.Save(stream, ImageFormat.Png);
                    pngData = stream.ToArray();
                }
            }

            List <MultipartForm.Element> postParameters = new List <MultipartForm.Element>()
            {
                new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
                new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
                new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
            };

            // Make the remote storage request
            try
            {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);

                HttpWebResponse response = MultipartForm.Post(request, postParameters);
                using (Stream responseStream = response.GetResponseStream())
                {
                    string responseStr = null;

                    try
                    {
                        responseStr = responseStream.GetStreamString();
                        OSD responseOSD = OSDParser.Deserialize(responseStr);
                        if (responseOSD.Type == OSDType.Map)
                        {
                            OSDMap responseMap = (OSDMap)responseOSD;
                            if (responseMap["Success"].AsBoolean())
                            {
                                m_log.Info("[SIMIAN GRID CONNECTOR]: Uploaded " + pngData.Length + " byte PNG map tile to AddMapTile");
                            }
                            else
                            {
                                errorMessage = "Upload failed: " + responseMap["Message"].AsString();
                            }
                        }
                        else
                        {
                            errorMessage = "Response format was invalid:\n" + responseStr;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!String.IsNullOrEmpty(responseStr))
                        {
                            errorMessage = "Failed to parse the response:\n" + responseStr;
                        }
                        else
                        {
                            errorMessage = "Failed to retrieve the response: " + ex.Message;
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                errorMessage = ex.Message;
            }

            if (!String.IsNullOrEmpty(errorMessage))
            {
                m_log.WarnFormat("[SIMIAN GRID CONNECTOR]: Failed to store {0} byte PNG map tile for {1}: {2}",
                                 pngData.Length, scene.RegionInfo.RegionName, errorMessage.Replace('\n', ' '));
            }
        }
Beispiel #8
0
        public void CreateMapTileAsync(object worthless)
        {
            IMapImageGenerator terrain = m_scene.RequestModuleInterface <IMapImageGenerator>();

            if (terrain == null)
            {
                return;
            }

            bool changed = false;

            byte[] terraindata, mapdata;
            terrain.CreateMapTile(out terraindata, out mapdata);
            if (terraindata != null)
            {
                UUID newID = UUID.Zero;
                if (m_scene.RegionInfo.RegionSettings.TerrainMapImageID != UUID.Zero)
                {
                    m_scene.AssetService.UpdateContent(m_scene.RegionInfo.RegionSettings.TerrainMapImageID, terraindata, out newID);
                    m_scene.RegionInfo.RegionSettings.TerrainMapImageID = newID;
                    changed = true;
                }

                if (m_scene.RegionInfo.RegionSettings.TerrainMapImageID == UUID.Zero)
                {
                    AssetBase Terrainasset = new AssetBase(
                        UUID.Random(),
                        "terrainMapImage_" + m_scene.RegionInfo.RegionID.ToString(),
                        AssetType.Simstate,
                        m_scene.RegionInfo.RegionID)
                    {
                        Data        = terraindata,
                        Description = m_scene.RegionInfo.RegionName,
                        Flags       = AssetFlags.Deletable | AssetFlags.Rewritable | AssetFlags.Maptile
                    };
                    newID = m_scene.AssetService.Store(Terrainasset);
                }

                if (m_scene.RegionInfo.RegionSettings.TerrainMapImageID != newID)
                {
                    m_scene.RegionInfo.RegionSettings.TerrainMapImageID = newID;
                    changed = true;
                }
            }

            if (mapdata != null)
            {
                UUID newID = UUID.Zero;
                if (m_scene.RegionInfo.RegionSettings.TerrainImageID != UUID.Zero)
                {
                    m_scene.AssetService.UpdateContent(m_scene.RegionInfo.RegionSettings.TerrainImageID, mapdata, out newID);
                    m_scene.RegionInfo.RegionSettings.TerrainImageID = newID;
                    changed = true;
                }

                if (m_scene.RegionInfo.RegionSettings.TerrainImageID == UUID.Zero)
                {
                    AssetBase Mapasset = new AssetBase(
                        UUID.Random(),
                        "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(),
                        AssetType.Simstate,
                        m_scene.RegionInfo.RegionID)
                    {
                        Data        = mapdata,
                        Description = m_scene.RegionInfo.RegionName,
                        Flags       = AssetFlags.Deletable | AssetFlags.Rewritable | AssetFlags.Maptile
                    };
                    newID = m_scene.AssetService.Store(Mapasset);
                }

                if (m_scene.RegionInfo.RegionSettings.TerrainImageID != newID)
                {
                    m_scene.RegionInfo.RegionSettings.TerrainImageID = newID;
                    changed = true;
                }
            }

            if (changed)//Make sure to update the db with the new settings
            {
                m_scene.RegionInfo.RegionSettings.Save();
            }

            //Update the grid map
            IGridRegisterModule gridRegModule = m_scene.RequestModuleInterface <IGridRegisterModule>();

            if (gridRegModule != null)
            {
                gridRegModule.UpdateGridRegion(m_scene);
            }
        }
Beispiel #9
0
        public void CreateMapTileAsync(object worthless)
        {
            IMapImageGenerator terrain = m_scene.RequestModuleInterface <IMapImageGenerator>();

            if (terrain == null)
            {
                return;
            }

            byte[] terraindata, mapdata;
            terrain.CreateMapTile(out terraindata, out mapdata);
            if (terraindata != null)
            {
                if (m_scene.RegionInfo.RegionSettings.TerrainMapImageID != UUID.Zero)
                {
                    m_scene.RegionInfo.RegionSettings.TerrainMapImageID =
                        m_scene.AssetService.UpdateContent(m_scene.RegionInfo.RegionSettings.TerrainMapImageID,
                                                           terraindata);
                }
                if (m_scene.RegionInfo.RegionSettings.TerrainMapImageID == UUID.Zero)
                //Do not optimize away! UpdateContent can fail sometimes!
                {
                    AssetBase Terrainasset = new AssetBase(
                        UUID.Random(),
                        "terrainMapImage_" + m_scene.RegionInfo.RegionID.ToString(),
                        AssetType.Simstate,
                        m_scene.RegionInfo.RegionID)
                    {
                        Data        = terraindata,
                        Description = m_scene.RegionInfo.RegionName,
                        Flags       =
                            AssetFlags.Deletable | AssetFlags.Rewritable |
                            AssetFlags.Maptile
                    };
                    m_scene.RegionInfo.RegionSettings.TerrainMapImageID = m_scene.AssetService.Store(Terrainasset);
                }
            }

            if (mapdata != null)
            {
                if (m_scene.RegionInfo.RegionSettings.TerrainImageID != UUID.Zero)
                {
                    m_scene.RegionInfo.RegionSettings.TerrainImageID =
                        m_scene.AssetService.UpdateContent(m_scene.RegionInfo.RegionSettings.TerrainImageID, mapdata);
                }
                if (m_scene.RegionInfo.RegionSettings.TerrainImageID == UUID.Zero)
                //Do not optimize away! UpdateContent can fail sometimes!
                {
                    AssetBase Mapasset = new AssetBase(
                        UUID.Random(),
                        "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(),
                        AssetType.Simstate,
                        m_scene.RegionInfo.RegionID)
                    {
                        Data        = mapdata,
                        Description = m_scene.RegionInfo.RegionName,
                        Flags       =
                            AssetFlags.Deletable | AssetFlags.Rewritable | AssetFlags.Maptile
                    };
                    m_scene.RegionInfo.RegionSettings.TerrainImageID = m_scene.AssetService.Store(Mapasset);
                }
            }

            byte[] overlay = GenerateOverlay();
            if (overlay != null)
            {
                if (m_scene.RegionInfo.RegionSettings.ParcelMapImageID != UUID.Zero)
                {
                    m_scene.RegionInfo.RegionSettings.ParcelMapImageID =
                        m_scene.AssetService.UpdateContent(m_scene.RegionInfo.RegionSettings.ParcelMapImageID, overlay);
                }
                if (m_scene.RegionInfo.RegionSettings.ParcelMapImageID == UUID.Zero)
                //Do not optimize away! UpdateContent can fail sometimes!
                {
                    AssetBase Parcelasset = new AssetBase(
                        UUID.Random(),
                        "terrainMapImage_" + m_scene.RegionInfo.RegionID.ToString(),
                        AssetType.Simstate,
                        m_scene.RegionInfo.RegionID)
                    {
                        Data        = overlay,
                        Description = m_scene.RegionInfo.RegionName,
                        Flags       =
                            AssetFlags.Deletable | AssetFlags.Rewritable |
                            AssetFlags.Maptile
                    };
                    m_scene.RegionInfo.RegionSettings.ParcelMapImageID = m_scene.AssetService.Store(Parcelasset);
                }
            }
            else
            {
                m_scene.RegionInfo.RegionSettings.ParcelMapImageID = UUID.Zero;
            }

            m_scene.RegionInfo.RegionSettings.TerrainMapLastRegenerated = DateTime.Now;

            //Update the grid map
            IGridRegisterModule gridRegModule = m_scene.RequestModuleInterface <IGridRegisterModule>();

            if (gridRegModule != null)
            {
                gridRegModule.UpdateGridRegion(m_scene);
            }
        }
        ///<summary>
        ///
        ///</summary>
        private void UploadMapTile(IScene scene)
        {
            m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}", scene.RegionInfo.RegionName);

            // Create a PNG map tile and upload it to the AddMapTile API
            byte[]             pngData       = Utils.EmptyBytes;
            IMapImageGenerator tileGenerator = scene.RequestModuleInterface <IMapImageGenerator>();

            if (tileGenerator == null)
            {
                m_log.Warn("[SIMIAN MAPTILE]: Cannot upload PNG map tile without an ImageGenerator");
                return;
            }

            using (Image mapTile = tileGenerator.CreateMapTile())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    mapTile.Save(stream, ImageFormat.Png);
                    pngData = stream.ToArray();
                }
            }

            NameValueCollection requestArgs = new NameValueCollection
            {
                { "RequestMethod", "xAddMapTile" },
                { "X", scene.RegionInfo.RegionLocX.ToString() },
                { "Y", scene.RegionInfo.RegionLocY.ToString() },
                { "ContentType", "image/png" },
                { "EncodedData", System.Convert.ToBase64String(pngData) }
            };

            OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);

            if (!response["Success"].AsBoolean())
            {
                m_log.WarnFormat("[SIMIAN MAPTILE] failed to store map tile; {0}", response["Message"].AsString());
                return;
            }

            // List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
            // {
            //     new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
            //     new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
            //     new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
            // };

            // string errorMessage = null;
            // int tickstart = Util.EnvironmentTickCount();

            // // Make the remote storage request
            // try
            // {
            //     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
            //     request.Timeout = 20000;
            //     request.ReadWriteTimeout = 5000;

            //     using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
            //     {
            //         using (Stream responseStream = response.GetResponseStream())
            //         {
            //             string responseStr = responseStream.GetStreamString();
            //             OSD responseOSD = OSDParser.Deserialize(responseStr);
            //             if (responseOSD.Type == OSDType.Map)
            //             {
            //                 OSDMap responseMap = (OSDMap)responseOSD;
            //                 if (responseMap["Success"].AsBoolean())
            //                     return;

            //                 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
            //             }
            //             else
            //             {
            //                 errorMessage = "Response format was invalid:\n" + responseStr;
            //             }
            //         }
            //     }
            // }
            // catch (WebException we)
            // {
            //     errorMessage = we.Message;
            //     if (we.Status == WebExceptionStatus.ProtocolError)
            //     {
            //         HttpWebResponse webResponse = (HttpWebResponse)we.Response;
            //         errorMessage = String.Format("[{0}] {1}",
            //                                      webResponse.StatusCode,webResponse.StatusDescription);
            //     }
            // }
            // catch (Exception ex)
            // {
            //     errorMessage = ex.Message;
            // }
            // finally
            // {
            //     // This just dumps a warning for any operation that takes more than 100 ms
            //     int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
            //     m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff);
            // }

            // m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}",
            //                  pngData.Length, scene.RegionInfo.RegionName, errorMessage);
        }