diff --git a/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs index d19e6b6ae1..fab92e4444 100644 --- a/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs @@ -38,9 +38,12 @@ namespace OpenSim.Region.Environment.Interfaces LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer); - + LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, + int updateTimer, bool SetBlending, byte AlphaValue); LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, string extraParams, int updateTimer); + LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, string extraParams, + int updateTimer, bool SetBlending, byte AlphaValue); } public interface IDynamicTextureRender diff --git a/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs b/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs index fe7b763425..2988feb5a9 100644 --- a/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs +++ b/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs @@ -27,12 +27,14 @@ */ using System; +using System.Drawing; using System.Collections.Generic; using libsecondlife; using Nini.Config; using OpenSim.Framework; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; +using OpenJPEGNet; namespace OpenSim.Region.Environment.Modules { @@ -93,8 +95,15 @@ namespace OpenSim.Region.Environment.Modules } } + public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer) + { + return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); + } + + public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, + string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) { if (RenderPlugins.ContainsKey(contentType)) { @@ -108,6 +117,8 @@ namespace OpenSim.Region.Environment.Modules updater.UpdateTimer = updateTimer; updater.UpdaterID = LLUUID.Random(); updater.Params = extraParams; + updater.BlendWithOldTexture = SetBlending; + updater.FrontAlpha = AlphaValue; if (!Updaters.ContainsKey(updater.UpdaterID)) { @@ -121,7 +132,13 @@ namespace OpenSim.Region.Environment.Modules } public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, - string extraParams, int updateTimer) + string extraParams, int updateTimer) + { + return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); + } + + public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, + string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) { if (RenderPlugins.ContainsKey(contentType)) { @@ -133,6 +150,8 @@ namespace OpenSim.Region.Environment.Modules updater.UpdateTimer = updateTimer; updater.UpdaterID = LLUUID.Random(); updater.Params = extraParams; + updater.BlendWithOldTexture = SetBlending; + updater.FrontAlpha = AlphaValue; if (!Updaters.ContainsKey(updater.UpdaterID)) { @@ -156,6 +175,9 @@ namespace OpenSim.Region.Environment.Modules public int UpdateTimer; public LLUUID LastAssetID; public string Params; + public bool BlendWithOldTexture = false; + public bool SetNewFrontAlpha = false; + public byte FrontAlpha = 255; public DynamicTextureUpdater() { @@ -166,9 +188,30 @@ namespace OpenSim.Region.Environment.Modules public void DataReceived(byte[] data, Scene scene) { + SceneObjectPart part = scene.GetSceneObjectPart(PrimID); + byte[] assetData; + AssetBase oldAsset = null; + if (BlendWithOldTexture) + { + LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; + oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); + if (oldAsset != null) + { + assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); + } + else + { + assetData = new byte[data.Length]; + Array.Copy(data, assetData, data.Length); + } + } + else + { + assetData = new byte[data.Length]; + Array.Copy(data, assetData, data.Length); + } + //TODO delete the last asset(data), if it was a dynamic texture - byte[] assetData = new byte[data.Length]; - Array.Copy(data, assetData, data.Length); AssetBase asset = new AssetBase(); asset.FullID = LLUUID.Random(); asset.Data = assetData; @@ -181,10 +224,53 @@ namespace OpenSim.Region.Environment.Modules LastAssetID = asset.FullID; - SceneObjectPart part = scene.GetSceneObjectPart(PrimID); + part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); part.ScheduleFullUpdate(); } + + private byte[] BlendTextures(byte[] frontImage, byte[] backImage) + { + return BlendTextures(frontImage, backImage, false, 0); + } + + private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) + { + Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); + Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); + if (setNewAlpha) + { + SetAlpha(ref image1, newAlpha); + } + Bitmap joint = MergeBitMaps(image1, image2); + + return OpenJPEG.EncodeFromImage(joint, true); + } + + public Bitmap MergeBitMaps(Bitmap front, Bitmap back) + { + Bitmap joint; + Graphics jG; + + joint = new Bitmap(back.Width, back.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + jG = Graphics.FromImage(joint); + + jG.DrawImage(back, 0, 0, back.Width, back.Height); + jG.DrawImage(front, 0, 0, back.Width, back.Height); + + return joint; + } + + private void SetAlpha(ref Bitmap b, byte alpha) + { + for (int w = 0; w < b.Width; w++) + { + for (int h = 0; h < b.Height; h++) + { + b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); + } + } + } } } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs b/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs index 0548b9d2d2..1bfc6477d2 100644 --- a/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs +++ b/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs @@ -38,6 +38,7 @@ using OpenSim.Region.Environment.Scenes; namespace OpenSim.Region.Environment.Modules { + public class LoadImageURLModule : IRegionModule, IDynamicTextureRender { private string m_name = "LoadImageURL"; @@ -55,7 +56,10 @@ namespace OpenSim.Region.Environment.Modules public void PostInitialise() { m_textureManager = m_scene.RequestModuleInterface(); - m_textureManager.RegisterRender(GetContentType(), this); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } } public void Close() diff --git a/OpenSim/Region/Environment/Modules/VectorRenderModule.cs b/OpenSim/Region/Environment/Modules/VectorRenderModule.cs new file mode 100644 index 0000000000..d03317098d --- /dev/null +++ b/OpenSim/Region/Environment/Modules/VectorRenderModule.cs @@ -0,0 +1,308 @@ + +using System; +using System.Drawing; +using System.IO; +using System.Net; +using System.Globalization; +using libsecondlife; +using Nini.Config; +using OpenJPEGNet; +using OpenSim.Framework; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Scenes; +//using Cairo; + +namespace OpenSim.Region.Environment.Modules +{ + public class VectorRenderModule : IRegionModule, IDynamicTextureRender + { + private Scene m_scene; + private string m_name = "VectorRenderModule"; + private IDynamicTextureManager m_textureManager; + + public VectorRenderModule() + { + } + + public void Initialise(Scene scene, IConfigSource config) + { + if (m_scene == null) + { + m_scene = scene; + } + } + + public void PostInitialise() + { + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } + } + + public void Close() + { + } + + public string Name + { + get { return m_name; } + } + + public bool IsSharedModule + { + get { return true; } + } + + private void Draw(string data, LLUUID id, string extraParams) + { + Bitmap bitmap = new Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bitmap); + + extraParams = extraParams.ToLower(); + int alpha = 255; + if (extraParams == "setalpha") + { + alpha = 0; + } + else + { + graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 256, 256); + } + + for (int w = 0; w < bitmap.Width; w++) + { + for (int h = 0; h < bitmap.Height; h++) + { + bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); + } + } + + + + GDIDraw(data, graph); + + byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); + m_textureManager.ReturnData(id, imageJ2000); + + } + + /* private void CairoDraw(string data, System.Drawing.Graphics graph) + { + using (Win32Surface draw = new Win32Surface(graph.GetHdc())) + { + Context contex = new Context(draw); + + contex.Antialias = Antialias.None; //fastest method but low quality + contex.LineWidth = 7; + char[] lineDelimiter = { ';' }; + char[] partsDelimiter = { ',' }; + string[] lines = data.Split(lineDelimiter); + + foreach (string line in lines) + { + string nextLine = line.Trim(); + + if (nextLine.StartsWith("MoveTO")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, ref x, ref y); + contex.MoveTo(x, y); + } + else if (nextLine.StartsWith("LineTo")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, ref x, ref y); + contex.LineTo(x, y); + contex.Stroke(); + } + } + } + graph.ReleaseHdc(); + }*/ + + private void GDIDraw(string data, System.Drawing.Graphics graph) + { + System.Drawing.Point startPoint = new System.Drawing.Point(0, 0); + System.Drawing.Point endPoint = new System.Drawing.Point(0, 0); + System.Drawing.Pen drawPen = new Pen(System.Drawing.Color.Black, 7); + Font myFont = new Font("Times New Roman", 14); + SolidBrush myBrush = new SolidBrush(Color.Black); + char[] lineDelimiter = { ';' }; + char[] partsDelimiter = { ',' }; + string[] lines = data.Split(lineDelimiter); + + + foreach (string line in lines) + { + string nextLine = line.Trim(); + + if (nextLine.StartsWith("MoveTo")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); + startPoint.X = (int)x; + startPoint.Y = (int)y; + } + else if (nextLine.StartsWith("LineTo")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + graph.DrawLine(drawPen, startPoint, endPoint); + startPoint.X = endPoint.X; + startPoint.Y = endPoint.Y; + } + else if (nextLine.StartsWith("Text")) + { + nextLine = nextLine.Remove(0, 4); + nextLine = nextLine.Trim(); + graph.DrawString(nextLine, myFont, myBrush, startPoint); + } + else if (nextLine.StartsWith("Image")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + System.Drawing.Image image = ImageHttpRequest(nextLine); + graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y); + startPoint.X += endPoint.X; + startPoint.Y += endPoint.Y; + } + else if (nextLine.StartsWith("Rectangle")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); + startPoint.X += endPoint.X; + startPoint.Y += endPoint.Y; + } + else if (nextLine.StartsWith("FillRectangle")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); + startPoint.X += endPoint.X; + startPoint.Y += endPoint.Y; + } + else if (nextLine.StartsWith("Ellipse")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); + startPoint.X += endPoint.X; + startPoint.Y += endPoint.Y; + } + else if (nextLine.StartsWith("FontSize")) + { + nextLine = nextLine.Remove(0, 8); + nextLine = nextLine.Trim(); + float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); + myFont = new Font("Times New Roman", size); + } + else if (nextLine.StartsWith("PenSize")) + { + nextLine = nextLine.Remove(0, 8); + nextLine = nextLine.Trim(); + float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); + drawPen.Width = size; + } + } + } + + private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) + { + line = line.Remove(0, startLength); + string[] parts = line.Split(partsDelimiter); + if (parts.Length == 2) + { + string xVal = parts[0].Trim(); + string yVal = parts[1].Trim(); + x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); + y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); + } + else if (parts.Length > 2) + { + string xVal = parts[0].Trim(); + string yVal = parts[1].Trim(); + x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); + y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); + + line = ""; + for (int i = 2; i < parts.Length; i++) + { + line = line + parts[i].Trim(); + line = line + " "; + } + } + } + + private Bitmap ImageHttpRequest(string url) + { + WebRequest request = HttpWebRequest.Create(url); + Stream str = null; + HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); + if (response.StatusCode == HttpStatusCode.OK) + { + Bitmap image = new Bitmap(response.GetResponseStream()); + return image; + } + + return null; + } + + public string GetContentType() + { + return ("vector"); + } + + public string GetName() + { + return m_name; + } + + public bool SupportsAsynchronous() + { + return true; + } + + public byte[] ConvertUrl(string url, string extraParams) + { + return null; + } + + public byte[] ConvertStream(Stream data, string extraParams) + { + return null; + } + + public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) + { + return false; + } + + public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) + { + Draw(bodyData, id, extraParams); + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs index 922b301160..79a106b056 100644 --- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs @@ -1849,6 +1849,24 @@ namespace OpenSim.Region.ScriptEngine.Common return m_LSL_Functions.osSetDynamicTextureURL(dynamicID, contentType, url, extraParams, timer); } + public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, + int timer) + { + return m_LSL_Functions.osSetDynamicTextureData(dynamicID, contentType, data, extraParams, timer); + } + + public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, + int timer, int alpha) + { + return m_LSL_Functions.osSetDynamicTextureURLBlend(dynamicID, contentType, url, extraParams, timer, alpha); + } + + public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, + int timer, int alpha) + { + return m_LSL_Functions.osSetDynamicTextureDataBlend(dynamicID, contentType, data, extraParams, timer, alpha); + } + public double osTerrainGetHeight(int x, int y) { return m_LSL_Functions.osTerrainGetHeight(x, y); diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 7da47d40d9..93de3b4ad7 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -4265,6 +4265,72 @@ namespace OpenSim.Region.ScriptEngine.Common return LLUUID.Zero.ToString(); } + public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, + int timer, int alpha) + { + m_host.AddScriptLPS(1); + if (dynamicID == String.Empty) + { + IDynamicTextureManager textureManager = World.RequestModuleInterface(); + LLUUID createdTexture = + textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, + extraParams, timer, true, (byte) alpha ); + return createdTexture.ToString(); + } + else + { + //TODO update existing dynamic textures + } + + return LLUUID.Zero.ToString(); + } + + public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, + int timer) + { + m_host.AddScriptLPS(1); + if (dynamicID == String.Empty) + { + IDynamicTextureManager textureManager = World.RequestModuleInterface(); + if (textureManager != null) + { + LLUUID createdTexture = + textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, + extraParams, timer); + return createdTexture.ToString(); + } + } + else + { + //TODO update existing dynamic textures + } + + return LLUUID.Zero.ToString(); + } + + public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, + int timer, int alpha) + { + m_host.AddScriptLPS(1); + if (dynamicID == String.Empty) + { + IDynamicTextureManager textureManager = World.RequestModuleInterface(); + if (textureManager != null) + { + LLUUID createdTexture = + textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, + extraParams, timer, true, (byte) alpha); + return createdTexture.ToString(); + } + } + else + { + //TODO update existing dynamic textures + } + + return LLUUID.Zero.ToString(); + } + public bool osConsoleCommand(string command) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs index c1e178b4b8..c6d683c42f 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs @@ -637,6 +637,11 @@ namespace OpenSim.Region.ScriptEngine.Common string llStringTrim(string src, int type); //OpenSim functions 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 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); double osTerrainGetHeight(int x, int y); int osTerrainSetHeight(int x, int y, double val); int osRegionRestart(double seconds);