diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/DynamicTexture')
-rw-r--r-- | OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs | 61 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | 315 |
2 files changed, 306 insertions, 70 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs new file mode 100644 index 0000000..fce9490 --- /dev/null +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs | |||
@@ -0,0 +1,61 @@ | |||
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 OpenSimulator 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 | |||
28 | using System; | ||
29 | using System.Drawing; | ||
30 | using OpenSim.Region.Framework.Interfaces; | ||
31 | |||
32 | namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | ||
33 | { | ||
34 | public class DynamicTexture : IDynamicTexture | ||
35 | { | ||
36 | public string InputCommands { get; private set; } | ||
37 | public Uri InputUri { get; private set; } | ||
38 | public string InputParams { get; private set; } | ||
39 | public byte[] Data { get; private set; } | ||
40 | public Size Size { get; private set; } | ||
41 | public bool IsReuseable { get; private set; } | ||
42 | |||
43 | public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable) | ||
44 | { | ||
45 | InputCommands = inputCommands; | ||
46 | InputParams = inputParams; | ||
47 | Data = data; | ||
48 | Size = size; | ||
49 | IsReuseable = isReuseable; | ||
50 | } | ||
51 | |||
52 | public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable) | ||
53 | { | ||
54 | InputUri = inputUri; | ||
55 | InputParams = inputParams; | ||
56 | Data = data; | ||
57 | Size = size; | ||
58 | IsReuseable = isReuseable; | ||
59 | } | ||
60 | } | ||
61 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 18bd018..9d77b19 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | |||
@@ -37,18 +37,36 @@ using OpenSim.Region.Framework.Interfaces; | |||
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using log4net; | 38 | using log4net; |
39 | using System.Reflection; | 39 | using System.Reflection; |
40 | using Mono.Addins; | ||
40 | 41 | ||
41 | namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | 42 | namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture |
42 | { | 43 | { |
43 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager | 44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicTextureModule")] |
45 | public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager | ||
44 | { | 46 | { |
45 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 48 | ||
47 | private const int ALL_SIDES = -1; | 49 | private const int ALL_SIDES = -1; |
48 | 50 | ||
49 | public const int DISP_EXPIRE = 1; | 51 | public const int DISP_EXPIRE = 1; |
50 | public const int DISP_TEMP = 2; | 52 | public const int DISP_TEMP = 2; |
51 | 53 | ||
54 | /// <summary> | ||
55 | /// If true then where possible dynamic textures are reused. | ||
56 | /// </summary> | ||
57 | public bool ReuseTextures { get; set; } | ||
58 | |||
59 | /// <summary> | ||
60 | /// If false, then textures which have a low data size are not reused when ReuseTextures = true. | ||
61 | /// </summary> | ||
62 | /// <remarks> | ||
63 | /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those | ||
64 | /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen | ||
65 | /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is | ||
66 | /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused | ||
67 | /// to work around this problem.</remarks> | ||
68 | public bool ReuseLowDataTextures { get; set; } | ||
69 | |||
52 | private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); | 70 | private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); |
53 | 71 | ||
54 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = | 72 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = |
@@ -56,6 +74,25 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
56 | 74 | ||
57 | private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); | 75 | private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); |
58 | 76 | ||
77 | /// <summary> | ||
78 | /// Record dynamic textures that we can reuse for a given data and parameter combination rather than | ||
79 | /// regenerate. | ||
80 | /// </summary> | ||
81 | /// <remarks> | ||
82 | /// Key is string.Format("{0}{1}", data | ||
83 | /// </remarks> | ||
84 | private Cache m_reuseableDynamicTextures; | ||
85 | |||
86 | /// <summary> | ||
87 | /// This constructor is only here because of the Unit Tests... | ||
88 | /// Don't use it. | ||
89 | /// </summary> | ||
90 | public DynamicTextureModule() | ||
91 | { | ||
92 | m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); | ||
93 | m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); | ||
94 | } | ||
95 | |||
59 | #region IDynamicTextureManager Members | 96 | #region IDynamicTextureManager Members |
60 | 97 | ||
61 | public void RegisterRender(string handleType, IDynamicTextureRender render) | 98 | public void RegisterRender(string handleType, IDynamicTextureRender render) |
@@ -69,17 +106,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
69 | /// <summary> | 106 | /// <summary> |
70 | /// Called by code which actually renders the dynamic texture to supply texture data. | 107 | /// Called by code which actually renders the dynamic texture to supply texture data. |
71 | /// </summary> | 108 | /// </summary> |
72 | /// <param name="id"></param> | 109 | /// <param name="updaterId"></param> |
73 | /// <param name="data"></param> | 110 | /// <param name="texture"></param> |
74 | public void ReturnData(UUID id, byte[] data) | 111 | public void ReturnData(UUID updaterId, IDynamicTexture texture) |
75 | { | 112 | { |
76 | DynamicTextureUpdater updater = null; | 113 | DynamicTextureUpdater updater = null; |
77 | 114 | ||
78 | lock (Updaters) | 115 | lock (Updaters) |
79 | { | 116 | { |
80 | if (Updaters.ContainsKey(id)) | 117 | if (Updaters.ContainsKey(updaterId)) |
81 | { | 118 | { |
82 | updater = Updaters[id]; | 119 | updater = Updaters[updaterId]; |
83 | } | 120 | } |
84 | } | 121 | } |
85 | 122 | ||
@@ -88,7 +125,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
88 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) | 125 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) |
89 | { | 126 | { |
90 | Scene scene = RegisteredScenes[updater.SimUUID]; | 127 | Scene scene = RegisteredScenes[updater.SimUUID]; |
91 | updater.DataReceived(data, scene); | 128 | UUID newTextureID = updater.DataReceived(texture.Data, scene); |
129 | |||
130 | if (ReuseTextures | ||
131 | && !updater.BlendWithOldTexture | ||
132 | && texture.IsReuseable | ||
133 | && (ReuseLowDataTextures || IsDataSizeReuseable(texture))) | ||
134 | { | ||
135 | m_reuseableDynamicTextures.Store( | ||
136 | GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID); | ||
137 | } | ||
92 | } | 138 | } |
93 | } | 139 | } |
94 | 140 | ||
@@ -104,6 +150,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
104 | } | 150 | } |
105 | } | 151 | } |
106 | 152 | ||
153 | /// <summary> | ||
154 | /// Determines whether the texture is reuseable based on its data size. | ||
155 | /// </summary> | ||
156 | /// <remarks> | ||
157 | /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size | ||
158 | /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard | ||
159 | /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5). | ||
160 | /// </remarks> | ||
161 | /// <returns></returns> | ||
162 | private bool IsDataSizeReuseable(IDynamicTexture texture) | ||
163 | { | ||
164 | // Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height); | ||
165 | int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5); | ||
166 | |||
167 | // m_log.DebugFormat( | ||
168 | // "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}", | ||
169 | // discardLevel2DataThreshold, texture.Data.Length); | ||
170 | |||
171 | return discardLevel2DataThreshold < texture.Data.Length; | ||
172 | } | ||
173 | |||
107 | public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, | 174 | public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, |
108 | string extraParams, int updateTimer) | 175 | string extraParams, int updateTimer) |
109 | { | 176 | { |
@@ -167,22 +234,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
167 | public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, | 234 | public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, |
168 | string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) | 235 | string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) |
169 | { | 236 | { |
170 | if (RenderPlugins.ContainsKey(contentType)) | 237 | if (!RenderPlugins.ContainsKey(contentType)) |
238 | return UUID.Zero; | ||
239 | |||
240 | Scene scene; | ||
241 | RegisteredScenes.TryGetValue(simID, out scene); | ||
242 | |||
243 | if (scene == null) | ||
244 | return UUID.Zero; | ||
245 | |||
246 | SceneObjectPart part = scene.GetSceneObjectPart(primID); | ||
247 | |||
248 | if (part == null) | ||
249 | return UUID.Zero; | ||
250 | |||
251 | // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire | ||
252 | // them. | ||
253 | if (ReuseTextures) | ||
254 | disp = disp & ~DISP_EXPIRE; | ||
255 | |||
256 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | ||
257 | updater.SimUUID = simID; | ||
258 | updater.PrimID = primID; | ||
259 | updater.ContentType = contentType; | ||
260 | updater.BodyData = data; | ||
261 | updater.UpdateTimer = updateTimer; | ||
262 | updater.UpdaterID = UUID.Random(); | ||
263 | updater.Params = extraParams; | ||
264 | updater.BlendWithOldTexture = SetBlending; | ||
265 | updater.FrontAlpha = AlphaValue; | ||
266 | updater.Face = face; | ||
267 | updater.Url = "Local image"; | ||
268 | updater.Disp = disp; | ||
269 | |||
270 | object objReusableTextureUUID = null; | ||
271 | |||
272 | if (ReuseTextures && !updater.BlendWithOldTexture) | ||
171 | { | 273 | { |
172 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | 274 | string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams); |
173 | updater.SimUUID = simID; | 275 | objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey); |
174 | updater.PrimID = primID; | ||
175 | updater.ContentType = contentType; | ||
176 | updater.BodyData = data; | ||
177 | updater.UpdateTimer = updateTimer; | ||
178 | updater.UpdaterID = UUID.Random(); | ||
179 | updater.Params = extraParams; | ||
180 | updater.BlendWithOldTexture = SetBlending; | ||
181 | updater.FrontAlpha = AlphaValue; | ||
182 | updater.Face = face; | ||
183 | updater.Url = "Local image"; | ||
184 | updater.Disp = disp; | ||
185 | 276 | ||
277 | if (objReusableTextureUUID != null) | ||
278 | { | ||
279 | // If something else has removed this temporary asset from the cache, detect and invalidate | ||
280 | // our cached uuid. | ||
281 | if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null) | ||
282 | { | ||
283 | m_reuseableDynamicTextures.Invalidate(reuseableTextureKey); | ||
284 | objReusableTextureUUID = null; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | // We cannot reuse a dynamic texture if the data is going to be blended with something already there. | ||
290 | if (objReusableTextureUUID == null) | ||
291 | { | ||
186 | lock (Updaters) | 292 | lock (Updaters) |
187 | { | 293 | { |
188 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 294 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
@@ -191,11 +297,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
191 | } | 297 | } |
192 | } | 298 | } |
193 | 299 | ||
300 | // m_log.DebugFormat( | ||
301 | // "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}", | ||
302 | // part.Name, part.ParentGroup.Scene.Name); | ||
303 | |||
194 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | 304 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); |
195 | return updater.UpdaterID; | ||
196 | } | 305 | } |
197 | 306 | else | |
198 | return UUID.Zero; | 307 | { |
308 | // m_log.DebugFormat( | ||
309 | // "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}", | ||
310 | // objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name); | ||
311 | |||
312 | // No need to add to updaters as the texture is always the same. Not that this functionality | ||
313 | // apppears to be implemented anyway. | ||
314 | updater.UpdatePart(part, (UUID)objReusableTextureUUID); | ||
315 | } | ||
316 | |||
317 | return updater.UpdaterID; | ||
318 | } | ||
319 | |||
320 | private string GenerateReusableTextureKey(string data, string extraParams) | ||
321 | { | ||
322 | return string.Format("{0}{1}", data, extraParams); | ||
199 | } | 323 | } |
200 | 324 | ||
201 | public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, | 325 | public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, |
@@ -211,9 +335,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
211 | 335 | ||
212 | #endregion | 336 | #endregion |
213 | 337 | ||
214 | #region IRegionModule Members | 338 | #region ISharedRegionModule Members |
215 | 339 | ||
216 | public void Initialise(Scene scene, IConfigSource config) | 340 | public void Initialise(IConfigSource config) |
341 | { | ||
342 | IConfig texturesConfig = config.Configs["Textures"]; | ||
343 | if (texturesConfig != null) | ||
344 | { | ||
345 | ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); | ||
346 | ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false); | ||
347 | |||
348 | if (ReuseTextures) | ||
349 | { | ||
350 | m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); | ||
351 | m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | public void PostInitialise() | ||
357 | { | ||
358 | } | ||
359 | |||
360 | public void AddRegion(Scene scene) | ||
217 | { | 361 | { |
218 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 362 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
219 | { | 363 | { |
@@ -222,8 +366,14 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
222 | } | 366 | } |
223 | } | 367 | } |
224 | 368 | ||
225 | public void PostInitialise() | 369 | public void RegionLoaded(Scene scene) |
370 | { | ||
371 | } | ||
372 | |||
373 | public void RemoveRegion(Scene scene) | ||
226 | { | 374 | { |
375 | if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | ||
376 | RegisteredScenes.Remove(scene.RegionInfo.RegionID); | ||
227 | } | 377 | } |
228 | 378 | ||
229 | public void Close() | 379 | public void Close() |
@@ -235,9 +385,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
235 | get { return "DynamicTextureModule"; } | 385 | get { return "DynamicTextureModule"; } |
236 | } | 386 | } |
237 | 387 | ||
238 | public bool IsSharedModule | 388 | public Type ReplaceableInterface |
239 | { | 389 | { |
240 | get { return true; } | 390 | get { return null; } |
241 | } | 391 | } |
242 | 392 | ||
243 | #endregion | 393 | #endregion |
@@ -269,9 +419,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
269 | } | 419 | } |
270 | 420 | ||
271 | /// <summary> | 421 | /// <summary> |
422 | /// Update the given part with the new texture. | ||
423 | /// </summary> | ||
424 | /// <returns> | ||
425 | /// The old texture UUID. | ||
426 | /// </returns> | ||
427 | public UUID UpdatePart(SceneObjectPart part, UUID textureID) | ||
428 | { | ||
429 | UUID oldID; | ||
430 | |||
431 | lock (part) | ||
432 | { | ||
433 | // mostly keep the values from before | ||
434 | Primitive.TextureEntry tmptex = part.Shape.Textures; | ||
435 | |||
436 | // FIXME: Need to return the appropriate ID if only a single face is replaced. | ||
437 | oldID = tmptex.DefaultTexture.TextureID; | ||
438 | |||
439 | if (Face == ALL_SIDES) | ||
440 | { | ||
441 | oldID = tmptex.DefaultTexture.TextureID; | ||
442 | tmptex.DefaultTexture.TextureID = textureID; | ||
443 | } | ||
444 | else | ||
445 | { | ||
446 | try | ||
447 | { | ||
448 | Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); | ||
449 | texface.TextureID = textureID; | ||
450 | tmptex.FaceTextures[Face] = texface; | ||
451 | } | ||
452 | catch (Exception) | ||
453 | { | ||
454 | tmptex.DefaultTexture.TextureID = textureID; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | // I'm pretty sure we always want to force this to true | ||
459 | // I'm pretty sure noone whats to set fullbright true if it wasn't true before. | ||
460 | // tmptex.DefaultTexture.Fullbright = true; | ||
461 | |||
462 | part.UpdateTextureEntry(tmptex.GetBytes()); | ||
463 | } | ||
464 | |||
465 | return oldID; | ||
466 | } | ||
467 | |||
468 | /// <summary> | ||
272 | /// Called once new texture data has been received for this updater. | 469 | /// Called once new texture data has been received for this updater. |
273 | /// </summary> | 470 | /// </summary> |
274 | public void DataReceived(byte[] data, Scene scene) | 471 | /// <param name="data"></param> |
472 | /// <param name="scene"></param> | ||
473 | /// <param name="isReuseable">True if the data given is reuseable.</param> | ||
474 | /// <returns>The asset UUID given to the incoming data.</returns> | ||
475 | public UUID DataReceived(byte[] data, Scene scene) | ||
275 | { | 476 | { |
276 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | 477 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); |
277 | 478 | ||
@@ -281,7 +482,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
281 | String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); | 482 | String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); |
282 | scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, | 483 | scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, |
283 | 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); | 484 | 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); |
284 | return; | 485 | |
486 | return UUID.Zero; | ||
285 | } | 487 | } |
286 | 488 | ||
287 | byte[] assetData = null; | 489 | byte[] assetData = null; |
@@ -319,56 +521,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
319 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); | 521 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); |
320 | if (cacheLayerDecode != null) | 522 | if (cacheLayerDecode != null) |
321 | { | 523 | { |
322 | cacheLayerDecode.Decode(asset.FullID, asset.Data); | 524 | if (!cacheLayerDecode.Decode(asset.FullID, asset.Data)) |
323 | cacheLayerDecode = null; | 525 | m_log.WarnFormat( |
526 | "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed", | ||
527 | asset.ID, part.Name, part.ParentGroup.Scene.Name); | ||
324 | } | 528 | } |
325 | 529 | ||
326 | UUID oldID = UUID.Zero; | 530 | UUID oldID = UpdatePart(part, asset.FullID); |
327 | |||
328 | lock (part) | ||
329 | { | ||
330 | // mostly keep the values from before | ||
331 | Primitive.TextureEntry tmptex = part.Shape.Textures; | ||
332 | |||
333 | // remove the old asset from the cache | ||
334 | oldID = tmptex.DefaultTexture.TextureID; | ||
335 | |||
336 | if (Face == ALL_SIDES) | ||
337 | { | ||
338 | tmptex.DefaultTexture.TextureID = asset.FullID; | ||
339 | } | ||
340 | else | ||
341 | { | ||
342 | try | ||
343 | { | ||
344 | Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); | ||
345 | texface.TextureID = asset.FullID; | ||
346 | tmptex.FaceTextures[Face] = texface; | ||
347 | } | ||
348 | catch (Exception) | ||
349 | { | ||
350 | tmptex.DefaultTexture.TextureID = asset.FullID; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | // I'm pretty sure we always want to force this to true | ||
355 | // I'm pretty sure noone whats to set fullbright true if it wasn't true before. | ||
356 | // tmptex.DefaultTexture.Fullbright = true; | ||
357 | |||
358 | part.UpdateTextureEntry(tmptex.GetBytes()); | ||
359 | } | ||
360 | 531 | ||
361 | if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) | 532 | if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) |
362 | { | 533 | { |
363 | if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); | 534 | if (oldAsset == null) |
535 | oldAsset = scene.AssetService.Get(oldID.ToString()); | ||
536 | |||
364 | if (oldAsset != null) | 537 | if (oldAsset != null) |
365 | { | 538 | { |
366 | if (oldAsset.Temporary == true) | 539 | if (oldAsset.Temporary) |
367 | { | 540 | { |
368 | scene.AssetService.Delete(oldID.ToString()); | 541 | scene.AssetService.Delete(oldID.ToString()); |
369 | } | 542 | } |
370 | } | 543 | } |
371 | } | 544 | } |
545 | |||
546 | return asset.FullID; | ||
372 | } | 547 | } |
373 | 548 | ||
374 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) | 549 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) |