diff options
author | Mic Bowman | 2010-12-03 16:17:50 -0800 |
---|---|---|
committer | Melanie | 2010-12-03 23:45:00 +0000 |
commit | df860516bf4fa4e4196be4d5fc26db71d98334f4 (patch) | |
tree | cc941c190fe2647835b9453fdbaaccb85611986d /OpenSim/Region | |
parent | minor: change OpenSimBase log messages associated with newer module loader to... (diff) | |
download | opensim-SC-df860516bf4fa4e4196be4d5fc26db71d98334f4.zip opensim-SC-df860516bf4fa4e4196be4d5fc26db71d98334f4.tar.gz opensim-SC-df860516bf4fa4e4196be4d5fc26db71d98334f4.tar.bz2 opensim-SC-df860516bf4fa4e4196be4d5fc26db71d98334f4.tar.xz |
Various bug fixes for appearance handling: more aggressive reset of textures and vparams when appearance is not cached and when wearables change. Send appearance to the viewer with initial data.
Cleaned up (and added) debugging.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 99 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 46 |
2 files changed, 93 insertions, 52 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index ab1c206..7d6d191 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -115,8 +115,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
115 | 115 | ||
116 | #endregion | 116 | #endregion |
117 | 117 | ||
118 | /// <summary> | ||
119 | /// Check for the existence of the baked texture assets. Request a rebake | ||
120 | /// unless checkonly is true. | ||
121 | /// </summary> | ||
122 | /// <param name="client"></param> | ||
123 | /// <param name="checkonly"></param> | ||
118 | public bool ValidateBakedTextureCache(IClientAPI client) | 124 | public bool ValidateBakedTextureCache(IClientAPI client) |
119 | { | 125 | { |
126 | return ValidateBakedTextureCache(client, true); | ||
127 | } | ||
128 | |||
129 | private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) | ||
130 | { | ||
120 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 131 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
121 | if (sp == null) | 132 | if (sp == null) |
122 | { | 133 | { |
@@ -131,15 +142,33 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
131 | { | 142 | { |
132 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 143 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
133 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 144 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
134 | if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | 145 | |
146 | // if there is no texture entry, skip it | ||
147 | if (face == null) | ||
135 | continue; | 148 | continue; |
136 | 149 | ||
150 | // if the texture is one of the "defaults" then skip it | ||
151 | // this should probably be more intelligent (skirt texture doesnt matter | ||
152 | // if the avatar isnt wearing a skirt) but if any of the main baked | ||
153 | // textures is default then the rest should be as well | ||
154 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
155 | continue; | ||
156 | |||
137 | defonly = false; // found a non-default texture reference | 157 | defonly = false; // found a non-default texture reference |
138 | 158 | ||
139 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | 159 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) |
140 | return false; | 160 | { |
161 | // the asset didn't exist if we are only checking, then we found a bad | ||
162 | // one and we're done otherwise, ask for a rebake | ||
163 | if (checkonly) return false; | ||
164 | |||
165 | m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID); | ||
166 | client.SendRebakeAvatarTextures(face.TextureID); | ||
167 | } | ||
141 | } | 168 | } |
142 | 169 | ||
170 | m_log.InfoFormat("[AVFACTORY]: complete texture check for {0}",client.AgentId); | ||
171 | |||
143 | // If we only found default textures, then the appearance is not cached | 172 | // If we only found default textures, then the appearance is not cached |
144 | return (defonly ? false : true); | 173 | return (defonly ? false : true); |
145 | } | 174 | } |
@@ -158,55 +187,43 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
158 | return; | 187 | return; |
159 | } | 188 | } |
160 | 189 | ||
161 | // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); | 190 | m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}",client.AgentId); |
162 | 191 | ||
192 | // TODO: This is probably not necessary any longer, just assume the | ||
193 | // textureEntry set implies that the appearance transaction is complete | ||
163 | bool changed = false; | 194 | bool changed = false; |
164 | 195 | ||
165 | // Process the texture entry transactionally, this doesn't guarantee that Appearance is | 196 | // Process the texture entry transactionally, this doesn't guarantee that Appearance is |
166 | // going to be handled correctly but it does serialize the updates to the appearance | 197 | // going to be handled correctly but it does serialize the updates to the appearance |
167 | lock (m_setAppearanceLock) | 198 | lock (m_setAppearanceLock) |
168 | { | 199 | { |
200 | // Process the visual params, this may change height as well | ||
201 | if (visualParams != null) | ||
202 | { | ||
203 | changed = sp.Appearance.SetVisualParams(visualParams); | ||
204 | if (sp.Appearance.AvatarHeight > 0) | ||
205 | sp.SetHeight(sp.Appearance.AvatarHeight); | ||
206 | } | ||
207 | |||
208 | // Process the baked texture array | ||
169 | if (textureEntry != null) | 209 | if (textureEntry != null) |
170 | { | 210 | { |
171 | changed = sp.Appearance.SetTextureEntries(textureEntry); | 211 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; |
172 | 212 | ||
173 | // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId); | 213 | m_log.InfoFormat("[AVFACTORY]: received texture update for {0}",client.AgentId); |
214 | Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); }); | ||
174 | 215 | ||
175 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 216 | // This appears to be set only in the final stage of the appearance |
176 | { | 217 | // update transaction. In theory, we should be able to do an immediate |
177 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 218 | // appearance send and save here. |
178 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
179 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
180 | Util.FireAndForget(delegate(object o) { | ||
181 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
182 | client.SendRebakeAvatarTextures(face.TextureID); | ||
183 | }); | ||
184 | } | ||
185 | 219 | ||
186 | m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); | 220 | QueueAppearanceSave(client.AgentId); |
221 | QueueAppearanceSend(client.AgentId); | ||
187 | } | 222 | } |
188 | 223 | ||
189 | // Process the visual params, this may change height as well | ||
190 | if (visualParams != null) | ||
191 | { | ||
192 | if (sp.Appearance.SetVisualParams(visualParams)) | ||
193 | { | ||
194 | changed = true; | ||
195 | if (sp.Appearance.AvatarHeight > 0) | ||
196 | sp.SetHeight(sp.Appearance.AvatarHeight); | ||
197 | } | ||
198 | } | ||
199 | } | 224 | } |
200 | |||
201 | 225 | ||
202 | // If something changed in the appearance then queue an appearance save | 226 | // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); |
203 | if (changed) | ||
204 | QueueAppearanceSave(client.AgentId); | ||
205 | |||
206 | // And always queue up an appearance update to send out | ||
207 | QueueAppearanceSend(client.AgentId); | ||
208 | |||
209 | // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); | ||
210 | } | 227 | } |
211 | 228 | ||
212 | /// <summary> | 229 | /// <summary> |
@@ -229,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
229 | 246 | ||
230 | #region UpdateAppearanceTimer | 247 | #region UpdateAppearanceTimer |
231 | 248 | ||
249 | /// <summary> | ||
250 | /// Queue up a request to send appearance, makes it possible to | ||
251 | /// accumulate changes without sending out each one separately. | ||
252 | /// </summary> | ||
232 | public void QueueAppearanceSend(UUID agentid) | 253 | public void QueueAppearanceSend(UUID agentid) |
233 | { | 254 | { |
234 | // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); | 255 | // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); |
@@ -268,6 +289,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
268 | 289 | ||
269 | // Send the appearance to everyone in the scene | 290 | // Send the appearance to everyone in the scene |
270 | sp.SendAppearanceToAllOtherAgents(); | 291 | sp.SendAppearanceToAllOtherAgents(); |
292 | |||
293 | // Send animations back to the avatar as well | ||
294 | sp.Animator.SendAnimPack(); | ||
271 | } | 295 | } |
272 | 296 | ||
273 | private void HandleAppearanceSave(UUID agentid) | 297 | private void HandleAppearanceSave(UUID agentid) |
@@ -353,9 +377,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
353 | 377 | ||
354 | // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); | 378 | // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); |
355 | 379 | ||
380 | // we need to clean out the existing textures | ||
381 | sp.Appearance.ResetAppearance(); | ||
382 | |||
356 | // operate on a copy of the appearance so we don't have to lock anything | 383 | // operate on a copy of the appearance so we don't have to lock anything |
357 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); | 384 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); |
358 | 385 | ||
359 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 386 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
360 | { | 387 | { |
361 | if (wear.Type < AvatarWearable.MAX_WEARABLES) | 388 | if (wear.Type < AvatarWearable.MAX_WEARABLES) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 82214bf..a1c80e5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2418,30 +2418,44 @@ namespace OpenSim.Region.Framework.Scenes | |||
2418 | // the inventory arrives | 2418 | // the inventory arrives |
2419 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2419 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
2420 | 2420 | ||
2421 | // This agent just became root. We are going to tell everyone about it. The process of | 2421 | bool cachedappearance = false; |
2422 | // getting other avatars information was initiated in the constructor... don't do it | ||
2423 | // again here... | ||
2424 | SendAvatarDataToAllAgents(); | ||
2425 | 2422 | ||
2426 | // We have an appearance but we may not have the baked textures. Check the asset cache | 2423 | // We have an appearance but we may not have the baked textures. Check the asset cache |
2427 | // to see if all the baked textures are already here. | 2424 | // to see if all the baked textures are already here. |
2428 | if (m_scene.AvatarFactory != null) | 2425 | if (m_scene.AvatarFactory != null) |
2429 | { | 2426 | { |
2430 | if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) | 2427 | cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient); |
2431 | { | ||
2432 | // m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); | ||
2433 | SendAppearanceToAgent(this); | ||
2434 | |||
2435 | // If the avatars baked textures are all in the cache, then we have a | ||
2436 | // complete appearance... send it out, if not, then we'll send it when | ||
2437 | // the avatar finishes updating its appearance | ||
2438 | SendAppearanceToAllOtherAgents(); | ||
2439 | } | ||
2440 | } | 2428 | } |
2441 | else | 2429 | else |
2442 | { | 2430 | { |
2443 | m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); | 2431 | m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); |
2444 | } | 2432 | } |
2433 | |||
2434 | // If we aren't using a cached appearance, then clear out the baked textures | ||
2435 | if (! cachedappearance) | ||
2436 | { | ||
2437 | m_appearance.ResetAppearance(); | ||
2438 | if (m_scene.AvatarFactory != null) | ||
2439 | m_scene.AvatarFactory.QueueAppearanceSave(UUID); | ||
2440 | } | ||
2441 | |||
2442 | // This agent just became root. We are going to tell everyone about it. The process of | ||
2443 | // getting other avatars information was initiated in the constructor... don't do it | ||
2444 | // again here... this comes after the cached appearance check because the avatars | ||
2445 | // appearance goes into the avatar update packet | ||
2446 | SendAvatarDataToAllAgents(); | ||
2447 | SendAppearanceToAgent(this); | ||
2448 | |||
2449 | // If we are using the the cached appearance then send it out to everyone | ||
2450 | if (cachedappearance) | ||
2451 | { | ||
2452 | m_log.InfoFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); | ||
2453 | |||
2454 | // If the avatars baked textures are all in the cache, then we have a | ||
2455 | // complete appearance... send it out, if not, then we'll send it when | ||
2456 | // the avatar finishes updating its appearance | ||
2457 | SendAppearanceToAllOtherAgents(); | ||
2458 | } | ||
2445 | } | 2459 | } |
2446 | 2460 | ||
2447 | /// <summary> | 2461 | /// <summary> |
@@ -2501,7 +2515,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2501 | /// Send avatar data to an agent. | 2515 | /// Send avatar data to an agent. |
2502 | /// </summary> | 2516 | /// </summary> |
2503 | /// <param name="avatar"></param> | 2517 | /// <param name="avatar"></param> |
2504 | private void SendAvatarDataToAgent(ScenePresence avatar) | 2518 | public void SendAvatarDataToAgent(ScenePresence avatar) |
2505 | { | 2519 | { |
2506 | // m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); | 2520 | // m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); |
2507 | 2521 | ||
@@ -2569,7 +2583,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2569 | /// Send appearance data to an agent. | 2583 | /// Send appearance data to an agent. |
2570 | /// </summary> | 2584 | /// </summary> |
2571 | /// <param name="avatar"></param> | 2585 | /// <param name="avatar"></param> |
2572 | private void SendAppearanceToAgent(ScenePresence avatar) | 2586 | public void SendAppearanceToAgent(ScenePresence avatar) |
2573 | { | 2587 | { |
2574 | // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); | 2588 | // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); |
2575 | 2589 | ||