diff options
5 files changed, 147 insertions, 84 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 494ae5e..157feb5 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -53,6 +53,7 @@ namespace OpenSim.Framework | |||
53 | protected AvatarWearable[] m_wearables; | 53 | protected AvatarWearable[] m_wearables; |
54 | protected Dictionary<int, List<AvatarAttachment>> m_attachments; | 54 | protected Dictionary<int, List<AvatarAttachment>> m_attachments; |
55 | protected float m_avatarHeight = 0; | 55 | protected float m_avatarHeight = 0; |
56 | protected UUID[] m_texturehashes; | ||
56 | 57 | ||
57 | public virtual int Serial | 58 | public virtual int Serial |
58 | { | 59 | { |
@@ -98,6 +99,8 @@ namespace OpenSim.Framework | |||
98 | SetDefaultParams(); | 99 | SetDefaultParams(); |
99 | SetHeight(); | 100 | SetHeight(); |
100 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); | 101 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
102 | |||
103 | ResetTextureHashes(); | ||
101 | } | 104 | } |
102 | 105 | ||
103 | public AvatarAppearance(OSDMap map) | 106 | public AvatarAppearance(OSDMap map) |
@@ -108,32 +111,6 @@ namespace OpenSim.Framework | |||
108 | SetHeight(); | 111 | SetHeight(); |
109 | } | 112 | } |
110 | 113 | ||
111 | public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) | ||
112 | { | ||
113 | // m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance"); | ||
114 | |||
115 | m_serial = 0; | ||
116 | |||
117 | if (wearables != null) | ||
118 | m_wearables = wearables; | ||
119 | else | ||
120 | SetDefaultWearables(); | ||
121 | |||
122 | if (textureEntry != null) | ||
123 | m_texture = textureEntry; | ||
124 | else | ||
125 | SetDefaultTexture(); | ||
126 | |||
127 | if (visualParams != null) | ||
128 | m_visualparams = visualParams; | ||
129 | else | ||
130 | SetDefaultParams(); | ||
131 | |||
132 | SetHeight(); | ||
133 | |||
134 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); | ||
135 | } | ||
136 | |||
137 | public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) | 114 | public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) |
138 | { | 115 | { |
139 | } | 116 | } |
@@ -151,6 +128,8 @@ namespace OpenSim.Framework | |||
151 | SetHeight(); | 128 | SetHeight(); |
152 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); | 129 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
153 | 130 | ||
131 | ResetTextureHashes(); | ||
132 | |||
154 | return; | 133 | return; |
155 | } | 134 | } |
156 | 135 | ||
@@ -166,6 +145,10 @@ namespace OpenSim.Framework | |||
166 | SetWearable(i,appearance.Wearables[i]); | 145 | SetWearable(i,appearance.Wearables[i]); |
167 | } | 146 | } |
168 | 147 | ||
148 | m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT]; | ||
149 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | ||
150 | m_texturehashes[i] = new UUID(appearance.m_texturehashes[i]); | ||
151 | |||
169 | m_texture = null; | 152 | m_texture = null; |
170 | if (appearance.Texture != null) | 153 | if (appearance.Texture != null) |
171 | { | 154 | { |
@@ -200,6 +183,37 @@ namespace OpenSim.Framework | |||
200 | } | 183 | } |
201 | } | 184 | } |
202 | 185 | ||
186 | public void ResetTextureHashes() | ||
187 | { | ||
188 | m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT]; | ||
189 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | ||
190 | m_texturehashes[i] = UUID.Zero; | ||
191 | } | ||
192 | |||
193 | public UUID GetTextureHash(int textureIndex) | ||
194 | { | ||
195 | return m_texturehashes[NormalizeBakedTextureIndex(textureIndex)]; | ||
196 | } | ||
197 | |||
198 | public void SetTextureHash(int textureIndex, UUID textureHash) | ||
199 | { | ||
200 | m_texturehashes[NormalizeBakedTextureIndex(textureIndex)] = new UUID(textureHash); | ||
201 | } | ||
202 | |||
203 | /// <summary> | ||
204 | /// Normalizes the texture index to the actual bake index, this is done to | ||
205 | /// accommodate older viewers that send the BAKE_INDICES index rather than | ||
206 | /// the actual texture index | ||
207 | /// </summary> | ||
208 | private int NormalizeBakedTextureIndex(int textureIndex) | ||
209 | { | ||
210 | // Earlier viewer send the index into the baked index array, just trying to be careful here | ||
211 | if (textureIndex < BAKE_INDICES.Length) | ||
212 | return BAKE_INDICES[textureIndex]; | ||
213 | |||
214 | return textureIndex; | ||
215 | } | ||
216 | |||
203 | public void ClearWearables() | 217 | public void ClearWearables() |
204 | { | 218 | { |
205 | m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; | 219 | m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; |
@@ -223,12 +237,7 @@ namespace OpenSim.Framework | |||
223 | m_serial = 0; | 237 | m_serial = 0; |
224 | 238 | ||
225 | SetDefaultTexture(); | 239 | SetDefaultTexture(); |
226 | 240 | ResetTextureHashes(); | |
227 | //for (int i = 0; i < BAKE_INDICES.Length; i++) | ||
228 | // { | ||
229 | // int idx = BAKE_INDICES[i]; | ||
230 | // m_texture.FaceTextures[idx].TextureID = UUID.Zero; | ||
231 | // } | ||
232 | } | 241 | } |
233 | 242 | ||
234 | protected virtual void SetDefaultParams() | 243 | protected virtual void SetDefaultParams() |
@@ -598,6 +607,12 @@ namespace OpenSim.Framework | |||
598 | data["serial"] = OSD.FromInteger(m_serial); | 607 | data["serial"] = OSD.FromInteger(m_serial); |
599 | data["height"] = OSD.FromReal(m_avatarHeight); | 608 | data["height"] = OSD.FromReal(m_avatarHeight); |
600 | 609 | ||
610 | // Hashes | ||
611 | OSDArray hashes = new OSDArray(AvatarAppearance.TEXTURE_COUNT); | ||
612 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | ||
613 | hashes.Add(OSD.FromUUID(m_texturehashes[i])); | ||
614 | data["hashes"] = hashes; | ||
615 | |||
601 | // Wearables | 616 | // Wearables |
602 | OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES); | 617 | OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES); |
603 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) | 618 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) |
@@ -642,6 +657,25 @@ namespace OpenSim.Framework | |||
642 | 657 | ||
643 | try | 658 | try |
644 | { | 659 | { |
660 | // Hashes | ||
661 | m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT]; | ||
662 | if ((data != null) && (data["hashes"] != null) && (data["hashes"]).Type == OSDType.Array) | ||
663 | { | ||
664 | OSDArray hashes = (OSDArray)(data["hashes"]); | ||
665 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | ||
666 | { | ||
667 | UUID hashID = UUID.Zero; | ||
668 | if (i < hashes.Count && hashes[i] != null) | ||
669 | hashID = hashes[i].AsUUID(); | ||
670 | m_texturehashes[i] = hashID; | ||
671 | } | ||
672 | } | ||
673 | else | ||
674 | { | ||
675 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | ||
676 | m_texturehashes[i] = UUID.Zero; | ||
677 | } | ||
678 | |||
645 | // Wearables | 679 | // Wearables |
646 | SetDefaultWearables(); | 680 | SetDefaultWearables(); |
647 | if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) | 681 | if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 59ce2c4..1fffeff 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -66,7 +66,7 @@ namespace OpenSim.Framework | |||
66 | 66 | ||
67 | public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest); | 67 | public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest); |
68 | 68 | ||
69 | public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams); | 69 | public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> cachedTextureData); |
70 | 70 | ||
71 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); | 71 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); |
72 | 72 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e014471..dd8ef9c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -6214,7 +6214,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6214 | if (appear.ObjectData.TextureEntry.Length > 1) | 6214 | if (appear.ObjectData.TextureEntry.Length > 1) |
6215 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); | 6215 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); |
6216 | 6216 | ||
6217 | handlerSetAppearance(sender, te, visualparams); | 6217 | List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); |
6218 | for (int i = 0; i < appear.WearableData.Length; i++) | ||
6219 | { | ||
6220 | CachedTextureRequestArg arg = new CachedTextureRequestArg(); | ||
6221 | arg.BakedTextureIndex = appear.WearableData[i].TextureIndex; | ||
6222 | arg.WearableHashID = appear.WearableData[i].CacheID; | ||
6223 | hashes.Add(arg); | ||
6224 | } | ||
6225 | |||
6226 | handlerSetAppearance(sender, te, visualparams, hashes); | ||
6218 | } | 6227 | } |
6219 | catch (Exception e) | 6228 | catch (Exception e) |
6220 | { | 6229 | { |
@@ -11487,12 +11496,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11487 | requestArgs.Add(arg); | 11496 | requestArgs.Add(arg); |
11488 | } | 11497 | } |
11489 | 11498 | ||
11490 | CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; | 11499 | try |
11491 | if (handlerCachedTextureRequest != null) | 11500 | { |
11501 | CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; | ||
11502 | if (handlerCachedTextureRequest != null) | ||
11503 | { | ||
11504 | handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); | ||
11505 | } | ||
11506 | } | ||
11507 | catch (Exception e) | ||
11492 | { | 11508 | { |
11493 | handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); | 11509 | m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); |
11510 | return false; | ||
11494 | } | 11511 | } |
11495 | 11512 | ||
11496 | return true; | 11513 | return true; |
11497 | } | 11514 | } |
11498 | 11515 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b640b48..482bf6f 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
147 | /// <param name="visualParam"></param> | 147 | /// <param name="visualParam"></param> |
148 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) | 148 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) |
149 | { | 149 | { |
150 | SetAppearance(sp, appearance.Texture, appearance.VisualParams); | 150 | DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>()); |
151 | } | 151 | } |
152 | 152 | ||
153 | /// <summary> | 153 | /// <summary> |
@@ -158,9 +158,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
158 | /// <param name="visualParam"></param> | 158 | /// <param name="visualParam"></param> |
159 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) | 159 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) |
160 | { | 160 | { |
161 | // m_log.DebugFormat( | 161 | DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>()); |
162 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | 162 | } |
163 | // sp.Name, textureEntry, visualParams); | 163 | |
164 | /// <summary> | ||
165 | /// Set appearance data (texture asset IDs and slider settings) | ||
166 | /// </summary> | ||
167 | /// <param name="sp"></param> | ||
168 | /// <param name="texture"></param> | ||
169 | /// <param name="visualParam"></param> | ||
170 | protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) | ||
171 | { | ||
172 | // m_log.DebugFormat( | ||
173 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | ||
174 | // sp.Name, textureEntry, visualParams); | ||
164 | 175 | ||
165 | // TODO: This is probably not necessary any longer, just assume the | 176 | // TODO: This is probably not necessary any longer, just assume the |
166 | // textureEntry set implies that the appearance transaction is complete | 177 | // textureEntry set implies that the appearance transaction is complete |
@@ -190,18 +201,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
190 | // Process the baked texture array | 201 | // Process the baked texture array |
191 | if (textureEntry != null) | 202 | if (textureEntry != null) |
192 | { | 203 | { |
193 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); | 204 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); |
194 | 205 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | |
195 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | ||
196 | 206 | ||
197 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; | 207 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; |
198 | 208 | ||
199 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 209 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
200 | 210 | ||
201 | // If bake textures are missing and this is not an NPC, request a rebake from client | 211 | // If bake textures are missing and this is not an NPC, request a rebake from client |
202 | if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) | 212 | if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) |
203 | RequestRebake(sp, true); | 213 | RequestRebake(sp, true); |
204 | 214 | ||
215 | // Save the wearble hashes in the appearance | ||
216 | sp.Appearance.ResetTextureHashes(); | ||
217 | foreach (CachedTextureRequestArg arg in hashes) | ||
218 | sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID); | ||
219 | |||
205 | // This appears to be set only in the final stage of the appearance | 220 | // This appears to be set only in the final stage of the appearance |
206 | // update transaction. In theory, we should be able to do an immediate | 221 | // update transaction. In theory, we should be able to do an immediate |
207 | // appearance send and save here. | 222 | // appearance send and save here. |
@@ -235,13 +250,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
235 | 250 | ||
236 | public bool SendAppearance(UUID agentId) | 251 | public bool SendAppearance(UUID agentId) |
237 | { | 252 | { |
238 | // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); | 253 | // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); |
239 | 254 | ||
240 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 255 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
241 | if (sp == null) | 256 | if (sp == null) |
242 | { | 257 | { |
243 | // This is expected if the user has gone away. | 258 | // This is expected if the user has gone away. |
244 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | 259 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); |
245 | return false; | 260 | return false; |
246 | } | 261 | } |
247 | 262 | ||
@@ -318,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
318 | /// <param name="agentId"></param> | 333 | /// <param name="agentId"></param> |
319 | public void QueueAppearanceSend(UUID agentid) | 334 | public void QueueAppearanceSend(UUID agentid) |
320 | { | 335 | { |
321 | // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); | 336 | // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); |
322 | 337 | ||
323 | // 10000 ticks per millisecond, 1000 milliseconds per second | 338 | // 10000 ticks per millisecond, 1000 milliseconds per second |
324 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); | 339 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); |
@@ -331,7 +346,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
331 | 346 | ||
332 | public void QueueAppearanceSave(UUID agentid) | 347 | public void QueueAppearanceSave(UUID agentid) |
333 | { | 348 | { |
334 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); | 349 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); |
335 | 350 | ||
336 | // 10000 ticks per millisecond, 1000 milliseconds per second | 351 | // 10000 ticks per millisecond, 1000 milliseconds per second |
337 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); | 352 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); |
@@ -356,9 +371,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
356 | if (face == null) | 371 | if (face == null) |
357 | continue; | 372 | continue; |
358 | 373 | ||
359 | // m_log.DebugFormat( | 374 | // m_log.DebugFormat( |
360 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | 375 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", |
361 | // face.TextureID, idx, client.Name, client.AgentId); | 376 | // face.TextureID, idx, client.Name, client.AgentId); |
362 | 377 | ||
363 | // if the texture is one of the "defaults" then skip it | 378 | // if the texture is one of the "defaults" then skip it |
364 | // this should probably be more intelligent (skirt texture doesnt matter | 379 | // this should probably be more intelligent (skirt texture doesnt matter |
@@ -373,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
373 | return false; | 388 | return false; |
374 | } | 389 | } |
375 | 390 | ||
376 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 391 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); |
377 | 392 | ||
378 | // If we only found default textures, then the appearance is not cached | 393 | // If we only found default textures, then the appearance is not cached |
379 | return (defonly ? false : true); | 394 | return (defonly ? false : true); |
@@ -392,9 +407,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
392 | if (face == null) | 407 | if (face == null) |
393 | continue; | 408 | continue; |
394 | 409 | ||
395 | // m_log.DebugFormat( | 410 | // m_log.DebugFormat( |
396 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | 411 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", |
397 | // face.TextureID, idx, client.Name, client.AgentId); | 412 | // face.TextureID, idx, client.Name, client.AgentId); |
398 | 413 | ||
399 | // if the texture is one of the "defaults" then skip it | 414 | // if the texture is one of the "defaults" then skip it |
400 | // this should probably be more intelligent (skirt texture doesnt matter | 415 | // this should probably be more intelligent (skirt texture doesnt matter |
@@ -458,9 +473,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
458 | if (bakeType == BakeType.Unknown) | 473 | if (bakeType == BakeType.Unknown) |
459 | continue; | 474 | continue; |
460 | 475 | ||
461 | // m_log.DebugFormat( | 476 | // m_log.DebugFormat( |
462 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", | 477 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", |
463 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | 478 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); |
464 | 479 | ||
465 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); | 480 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); |
466 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture | 481 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture |
@@ -484,7 +499,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
484 | UUID avatarID = kvp.Key; | 499 | UUID avatarID = kvp.Key; |
485 | long sendTime = kvp.Value; | 500 | long sendTime = kvp.Value; |
486 | 501 | ||
487 | // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); | 502 | // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); |
488 | 503 | ||
489 | if (sendTime < now) | 504 | if (sendTime < now) |
490 | { | 505 | { |
@@ -530,11 +545,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
530 | if (sp == null) | 545 | if (sp == null) |
531 | { | 546 | { |
532 | // This is expected if the user has gone away. | 547 | // This is expected if the user has gone away. |
533 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | 548 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); |
534 | return; | 549 | return; |
535 | } | 550 | } |
536 | 551 | ||
537 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); | 552 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); |
538 | 553 | ||
539 | // This could take awhile since it needs to pull inventory | 554 | // This could take awhile since it needs to pull inventory |
540 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape | 555 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape |
@@ -622,12 +637,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
622 | /// <param name="client"></param> | 637 | /// <param name="client"></param> |
623 | /// <param name="texture"></param> | 638 | /// <param name="texture"></param> |
624 | /// <param name="visualParam"></param> | 639 | /// <param name="visualParam"></param> |
625 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | 640 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) |
626 | { | 641 | { |
627 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); | 642 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); |
628 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 643 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
629 | if (sp != null) | 644 | if (sp != null) |
630 | SetAppearance(sp, textureEntry, visualParams); | 645 | DoSetAppearance(sp, textureEntry, visualParams, hashes); |
631 | else | 646 | else |
632 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); | 647 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); |
633 | } | 648 | } |
@@ -684,7 +699,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
684 | /// <param name="cachedTextureRequest"></param> | 699 | /// <param name="cachedTextureRequest"></param> |
685 | private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) | 700 | private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) |
686 | { | 701 | { |
687 | // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); | 702 | // m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); |
688 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 703 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
689 | 704 | ||
690 | List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); | 705 | List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); |
@@ -695,23 +710,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
695 | 710 | ||
696 | if (m_reusetextures) | 711 | if (m_reusetextures) |
697 | { | 712 | { |
698 | // this is the most insanely dumb way to do this... however it seems to | 713 | if (sp.Appearance.GetTextureHash(index) == request.WearableHashID) |
699 | // actually work. if the appearance has been reset because wearables have | 714 | { |
700 | // changed then the texture entries are zero'd out until the bakes are | 715 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; |
701 | // uploaded. on login, if the textures exist in the cache (eg if you logged | 716 | if (face != null) |
702 | // into the simulator recently, then the appearance will pull those and send | 717 | texture = face.TextureID; |
703 | // them back in the packet and you won't have to rebake. if the textures aren't | 718 | } |
704 | // in the cache then the intial makeroot() call in scenepresence will zero | 719 | else |
705 | // them out. | 720 | { |
706 | // | 721 | // We know that that hash is wrong, null it out |
707 | // a better solution (though how much better is an open question) is to | 722 | // and wait for the setappearance call |
708 | // store the hashes in the appearance and compare them. Thats's coming. | 723 | sp.Appearance.SetTextureHash(index,UUID.Zero); |
709 | 724 | } | |
710 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; | 725 | |
711 | if (face != null) | 726 | // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID); |
712 | texture = face.TextureID; | ||
713 | |||
714 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); | ||
715 | } | 727 | } |
716 | 728 | ||
717 | CachedTextureResponseArg response = new CachedTextureResponseArg(); | 729 | CachedTextureResponseArg response = new CachedTextureResponseArg(); |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 384eb1f..118635d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -907,7 +907,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
907 | // Mimicking LLClientView which gets always set appearance from client. | 907 | // Mimicking LLClientView which gets always set appearance from client. |
908 | AvatarAppearance appearance; | 908 | AvatarAppearance appearance; |
909 | m_scene.GetAvatarAppearance(this, out appearance); | 909 | m_scene.GetAvatarAppearance(this, out appearance); |
910 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); | 910 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>()); |
911 | } | 911 | } |
912 | 912 | ||
913 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) | 913 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) |