aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/DynamicTexture
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/DynamicTexture')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs332
1 files changed, 332 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
new file mode 100644
index 0000000..e6a12a4
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -0,0 +1,332 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Drawing;
31using System.Drawing.Imaging;
32using OpenMetaverse;
33using OpenMetaverse.Imaging;
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38
39namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
40{
41 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
42 {
43 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
44
45 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
46 new Dictionary<string, IDynamicTextureRender>();
47
48 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
49
50 #region IDynamicTextureManager Members
51
52 public void RegisterRender(string handleType, IDynamicTextureRender render)
53 {
54 if (!RenderPlugins.ContainsKey(handleType))
55 {
56 RenderPlugins.Add(handleType, render);
57 }
58 }
59
60 /// <summary>
61 /// Called by code which actually renders the dynamic texture to supply texture data.
62 /// </summary>
63 /// <param name="id"></param>
64 /// <param name="data"></param>
65 public void ReturnData(UUID id, byte[] data)
66 {
67 if (Updaters.ContainsKey(id))
68 {
69 DynamicTextureUpdater updater = Updaters[id];
70 if (RegisteredScenes.ContainsKey(updater.SimUUID))
71 {
72 Scene scene = RegisteredScenes[updater.SimUUID];
73 updater.DataReceived(data, scene);
74 }
75 }
76 }
77
78 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
79 string extraParams, int updateTimer)
80 {
81 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255);
82 }
83
84 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
85 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
86 {
87 if (RenderPlugins.ContainsKey(contentType))
88 {
89 //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType);
90
91 DynamicTextureUpdater updater = new DynamicTextureUpdater();
92 updater.SimUUID = simID;
93 updater.PrimID = primID;
94 updater.ContentType = contentType;
95 updater.Url = url;
96 updater.UpdateTimer = updateTimer;
97 updater.UpdaterID = UUID.Random();
98 updater.Params = extraParams;
99 updater.BlendWithOldTexture = SetBlending;
100 updater.FrontAlpha = AlphaValue;
101
102 if (!Updaters.ContainsKey(updater.UpdaterID))
103 {
104 Updaters.Add(updater.UpdaterID, updater);
105 }
106
107 RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
108 return updater.UpdaterID;
109 }
110 return UUID.Zero;
111 }
112
113 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
114 string extraParams, int updateTimer)
115 {
116 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255);
117 }
118
119 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
120 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
121 {
122 if (RenderPlugins.ContainsKey(contentType))
123 {
124 DynamicTextureUpdater updater = new DynamicTextureUpdater();
125 updater.SimUUID = simID;
126 updater.PrimID = primID;
127 updater.ContentType = contentType;
128 updater.BodyData = data;
129 updater.UpdateTimer = updateTimer;
130 updater.UpdaterID = UUID.Random();
131 updater.Params = extraParams;
132 updater.BlendWithOldTexture = SetBlending;
133 updater.FrontAlpha = AlphaValue;
134
135 if (!Updaters.ContainsKey(updater.UpdaterID))
136 {
137 Updaters.Add(updater.UpdaterID, updater);
138 }
139
140 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
141 return updater.UpdaterID;
142 }
143 return UUID.Zero;
144 }
145
146 #endregion
147
148 #region IRegionModule Members
149
150 public void Initialise(Scene scene, IConfigSource config)
151 {
152 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
153 {
154 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
155 scene.RegisterModuleInterface<IDynamicTextureManager>(this);
156 }
157 }
158
159 public void PostInitialise()
160 {
161 }
162
163 public void Close()
164 {
165 }
166
167 public string Name
168 {
169 get { return "DynamicTextureModule"; }
170 }
171
172 public bool IsSharedModule
173 {
174 get { return true; }
175 }
176
177 #endregion
178
179 #region Nested type: DynamicTextureUpdater
180
181 public class DynamicTextureUpdater
182 {
183 public bool BlendWithOldTexture = false;
184 public string BodyData;
185 public string ContentType;
186 public byte FrontAlpha = 255;
187 public UUID LastAssetID;
188 public string Params;
189 public UUID PrimID;
190 public bool SetNewFrontAlpha = false;
191 public UUID SimUUID;
192 public UUID UpdaterID;
193 public int UpdateTimer;
194 public string Url;
195
196 public DynamicTextureUpdater()
197 {
198 LastAssetID = UUID.Zero;
199 UpdateTimer = 0;
200 BodyData = null;
201 }
202
203 /// <summary>
204 /// Called once new texture data has been received for this updater.
205 /// </summary>
206 public void DataReceived(byte[] data, Scene scene)
207 {
208 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
209 byte[] assetData;
210 AssetBase oldAsset = null;
211
212 if (BlendWithOldTexture)
213 {
214 UUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID;
215 oldAsset = scene.AssetCache.GetAsset(lastTextureID, true);
216 if (oldAsset != null)
217 {
218 assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
219 }
220 else
221 {
222 assetData = new byte[data.Length];
223 Array.Copy(data, assetData, data.Length);
224 }
225 }
226 else
227 {
228 assetData = new byte[data.Length];
229 Array.Copy(data, assetData, data.Length);
230 }
231
232 // Create a new asset for user
233 AssetBase asset = new AssetBase();
234 asset.Metadata.FullID = UUID.Random();
235 asset.Data = assetData;
236 asset.Metadata.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
237 asset.Metadata.Type = 0;
238 asset.Metadata.Description = "dynamic image";
239 asset.Metadata.Local = false;
240 asset.Metadata.Temporary = true;
241 scene.AssetCache.AddAsset(asset);
242
243 LastAssetID = asset.Metadata.FullID;
244
245 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
246 if (cacheLayerDecode != null)
247 {
248 cacheLayerDecode.syncdecode(asset.Metadata.FullID, asset.Data);
249 }
250 cacheLayerDecode = null;
251
252 // mostly keep the values from before
253 Primitive.TextureEntry tmptex = part.Shape.Textures;
254
255 // remove the old asset from the cache
256 UUID oldID = tmptex.DefaultTexture.TextureID;
257 scene.AssetCache.ExpireAsset(oldID);
258
259 tmptex.DefaultTexture.TextureID = asset.Metadata.FullID;
260 // I'm pretty sure we always want to force this to true
261 tmptex.DefaultTexture.Fullbright = true;
262
263 part.Shape.Textures = tmptex;
264 part.ScheduleFullUpdate();
265 }
266
267 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
268 {
269 ManagedImage managedImage;
270 Image image;
271
272 if (OpenJPEG.DecodeToImage(frontImage, out managedImage, out image))
273 {
274 Bitmap image1 = new Bitmap(image);
275
276 if (OpenJPEG.DecodeToImage(backImage, out managedImage, out image))
277 {
278 Bitmap image2 = new Bitmap(image);
279
280 if (setNewAlpha)
281 SetAlpha(ref image1, newAlpha);
282
283 Bitmap joint = MergeBitMaps(image1, image2);
284
285 byte[] result = new byte[0];
286
287 try
288 {
289 result = OpenJPEG.EncodeFromImage(joint, true);
290 }
291 catch (Exception)
292 {
293 Console.WriteLine(
294 "[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Empty byte data returned!");
295 }
296
297 return result;
298 }
299 }
300
301 return null;
302 }
303
304 public Bitmap MergeBitMaps(Bitmap front, Bitmap back)
305 {
306 Bitmap joint;
307 Graphics jG;
308
309 joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);
310 jG = Graphics.FromImage(joint);
311
312 jG.DrawImage(back, 0, 0, back.Width, back.Height);
313 jG.DrawImage(front, 0, 0, back.Width, back.Height);
314
315 return joint;
316 }
317
318 private void SetAlpha(ref Bitmap b, byte alpha)
319 {
320 for (int w = 0; w < b.Width; w++)
321 {
322 for (int h = 0; h < b.Height; h++)
323 {
324 b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h)));
325 }
326 }
327 }
328 }
329
330 #endregion
331 }
332}