From 3b689e506f82ea45fcf703b22eb50a00e40baa4f Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 22 May 2009 16:22:49 +0000 Subject: [PATCH] From: Alan Webb Changes to support client-side image pre-caching in the region. This commit adds an additional calling sequence to the DynamicTexture data and URL calls. The new interface allows a dynamic image to be loaded into a specific object face (rather than the mandatory ALL_SIDES supported today. This is in part fulfilment of ticket #458. --- .../DynamicTexture/DynamicTextureModule.cs | 59 +++++++++--- .../LoadImageURL/LoadImageURLModule.cs | 96 +++++++++++-------- .../Interfaces/IDynamicTextureManager.cs | 4 + .../Shared/Api/Implementation/OSSL_Api.cs | 51 ++++++++++ .../Shared/Api/Interface/IOSSL_Api.cs | 4 + .../Shared/Api/Runtime/OSSL_Stub.cs | 14 +++ 6 files changed, 178 insertions(+), 50 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 259a333e5f..6509bf3dce 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -42,6 +42,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { public class DynamicTextureModule : IRegionModule, IDynamicTextureManager { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private const int ALL_SIDES = -1; + private Dictionary RegisteredScenes = new Dictionary(); private Dictionary RenderPlugins = @@ -105,6 +109,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) + { + return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, SetBlending, AlphaValue, ALL_SIDES); + } + + public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, + string extraParams, int updateTimer, bool SetBlending, byte AlphaValue, int face) { if (RenderPlugins.ContainsKey(contentType)) { @@ -120,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.Params = extraParams; updater.BlendWithOldTexture = SetBlending; updater.FrontAlpha = AlphaValue; + updater.Face = face; lock (Updaters) { @@ -143,6 +154,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) + { + return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, SetBlending, AlphaValue, ALL_SIDES); + } + + public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, + string extraParams, int updateTimer, bool SetBlending, byte AlphaValue, int face) { if (RenderPlugins.ContainsKey(contentType)) { @@ -156,6 +173,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.Params = extraParams; updater.BlendWithOldTexture = SetBlending; updater.FrontAlpha = AlphaValue; + updater.Face = face; + updater.Url = "Local image"; lock (Updaters) { @@ -232,6 +251,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public UUID SimUUID; public UUID UpdaterID; public int UpdateTimer; + public int Face; public string Url; public DynamicTextureUpdater() @@ -249,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture SceneObjectPart part = scene.GetSceneObjectPart(PrimID); - if (data == null) + if (data == null || data.Length <= 1) { string msg = String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); @@ -287,34 +307,51 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture asset.Data = assetData; asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); asset.Type = 0; - asset.Description = "dynamic image"; + asset.Description = String.Format("URL image : {0}", Url); asset.Local = false; asset.Temporary = true; scene.AssetService.Store(asset); - LastAssetID = asset.FullID; - IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface(); if (cacheLayerDecode != null) { cacheLayerDecode.syncdecode(asset.FullID, asset.Data); + cacheLayerDecode = null; + LastAssetID = asset.FullID; } - cacheLayerDecode = null; // mostly keep the values from before Primitive.TextureEntry tmptex = part.Shape.Textures; - // remove the old asset from the cache - // UUID oldID = tmptex.DefaultTexture.TextureID; + // remove the old asset from the cache later + UUID oldID = tmptex.DefaultTexture.TextureID; - tmptex.DefaultTexture.TextureID = asset.FullID; + if (Face == ALL_SIDES) + { + tmptex.DefaultTexture.TextureID = asset.FullID; + } + else + { + try + { + Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); + texface.TextureID = asset.FullID; + tmptex.FaceTextures[Face] = texface; + } + catch(Exception) + { + tmptex.DefaultTexture.TextureID = asset.FullID; + } + } + // I'm pretty sure we always want to force this to true // I'm pretty sure noone whats to set fullbright true if it wasn't true before. // tmptex.DefaultTexture.Fullbright = true; - part.Shape.Textures = tmptex; - part.ScheduleFullUpdate(); - + part.UpdateTexture(tmptex); + + // scene.CommsManager.AssetCache.ExpireAsset(oldID); + scene.AssetService.Delete(oldID.ToString()); } private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 864d6ac448..61c37b971b 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -162,62 +162,80 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private void HttpRequestReturn(IAsyncResult result) { + RequestState state = (RequestState) result.AsyncState; WebRequest request = (WebRequest) state.Request; + Stream stream = null; + byte[] imageJ2000 = new byte[0]; + try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); - if (response.StatusCode == HttpStatusCode.OK) + if (response != null && response.StatusCode == HttpStatusCode.OK) { - Bitmap image = new Bitmap(response.GetResponseStream()); - Size newsize; + stream = response.GetResponseStream(); + if(stream != null) + { + Bitmap image = new Bitmap(stream); + Size newsize; - // TODO: make this a bit less hard coded - if ((image.Height < 64) && (image.Width < 64)) - { - newsize = new Size(32, 32); - } - else if ((image.Height < 128) && (image.Width < 128)) - { - newsize = new Size(64, 64); - } - else if ((image.Height < 256) && (image.Width < 256)) - { - newsize = new Size(128, 128); - } - else if ((image.Height < 512 && image.Width < 512)) - { - newsize = new Size(256, 256); - } - else if ((image.Height < 1024 && image.Width < 1024)) - { - newsize = new Size(512, 512); + // TODO: make this a bit less hard coded + if ((image.Height < 64) && (image.Width < 64)) + { + newsize = new Size(32, 32); + } + else if ((image.Height < 128) && (image.Width < 128)) + { + newsize = new Size(64, 64); + } + else if ((image.Height < 256) && (image.Width < 256)) + { + newsize = new Size(128, 128); + } + else if ((image.Height < 512 && image.Width < 512)) + { + newsize = new Size(256, 256); + } + else if ((image.Height < 1024 && image.Width < 1024)) + { + newsize = new Size(512, 512); + } + else + { + newsize = new Size(1024, 1024); + } + + Bitmap resize = new Bitmap(image, newsize); + + try + { + imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); + } + catch (Exception) + { + m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); + } } else { - newsize = new Size(1024, 1024); + m_log.WarnFormat("[LOADIMAGEURLMODULE] No data returned"); } - - Bitmap resize = new Bitmap(image, newsize); - byte[] imageJ2000 = new byte[0]; - - try - { - imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); - } - catch (Exception) - { - m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); - } - - m_textureManager.ReturnData(state.RequestID, imageJ2000); - return; } } catch (WebException) { } + finally + { + if(stream != null) + { + stream.Close(); + } + } + m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", + imageJ2000.Length, state.RequestID); + m_textureManager.ReturnData(state.RequestID, imageJ2000); } #region Nested type: RequestState diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs index 9b29209a48..80592d78a9 100644 --- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs @@ -39,10 +39,14 @@ namespace OpenSim.Region.Framework.Interfaces int updateTimer); UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, int updateTimer, bool SetBlending, byte AlphaValue); + UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, + int updateTimer, bool SetBlending, byte AlphaValue, int face); UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer); UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer, bool SetBlending, byte AlphaValue); + UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, + int updateTimer, bool SetBlending, byte AlphaValue, int face); void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, out double xSize, out double ySize); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fbae9c8a1f..91ee1b38b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -427,6 +427,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } + public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, + bool blend, int timer, int alpha, int face) + { + CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlendFace"); + + m_host.AddScriptLPS(1); + if (dynamicID == String.Empty) + { + IDynamicTextureManager textureManager = World.RequestModuleInterface(); + UUID createdTexture = + textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, + extraParams, timer, blend, (byte) alpha, face); + return createdTexture.ToString(); + } + else + { + //TODO update existing dynamic textures + } + + return UUID.Zero.ToString(); + } + public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer) { @@ -485,6 +507,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } + public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, + bool blend, int timer, int alpha, int face) + { + CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureDataBlendFace"); + + m_host.AddScriptLPS(1); + if (dynamicID == String.Empty) + { + IDynamicTextureManager textureManager = World.RequestModuleInterface(); + if (textureManager != null) + { + if (extraParams == String.Empty) + { + extraParams = "256"; + } + UUID createdTexture = + textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, + extraParams, timer, blend, (byte) alpha, face); + return createdTexture.ToString(); + } + } + else + { + //TODO update existing dynamic textures + } + + return UUID.Zero.ToString(); + } + public bool osConsoleCommand(string command) { CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 7c0f08683e..3360abeabb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -58,9 +58,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, int timer); string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, int timer, int alpha); + string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, + bool blend, int timer, int alpha, int face); string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer); string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, int timer, int alpha); + string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, + bool blend, int timer, int alpha, int face); LSL_Float osTerrainGetHeight(int x, int y); LSL_Integer osTerrainSetHeight(int x, int y, double val); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index a66ed30860..9d8920f80c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -134,6 +134,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osSetDynamicTextureDataBlend(dynamicID, contentType, data, extraParams, timer, alpha); } + public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, + bool blend, int timer, int alpha, int face) + { + return m_OSSL_Functions.osSetDynamicTextureURLBlendFace(dynamicID, contentType, url, extraParams, + blend, timer, alpha, face); + } + + public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, + bool blend, int timer, int alpha, int face) + { + return m_OSSL_Functions.osSetDynamicTextureDataBlendFace(dynamicID, contentType, data, extraParams, + blend, timer, alpha, face); + } + public LSL_Float osTerrainGetHeight(int x, int y) { return m_OSSL_Functions.osTerrainGetHeight(x, y);