Various bug fixes for appearance handling

avinationmerge
Mic Bowman 2010-11-29 16:24:16 -08:00 committed by Melanie
parent 0218845c2e
commit ab2adaf341
4 changed files with 114 additions and 58 deletions

View File

@ -238,11 +238,27 @@ namespace OpenSim.Framework
// } // }
} }
/// <summary>
/// Invalidate all of the baked textures in the appearance, useful
/// if you know that none are valid
/// </summary>
public virtual void ResetBakedTextures()
{
SetDefaultTexture();
//for (int i = 0; i < BAKE_INDICES.Length; i++)
// {
// int idx = BAKE_INDICES[i];
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
// }
}
protected virtual void SetDefaultTexture() protected virtual void SetDefaultTexture()
{ {
m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
for (uint i = 0; i < TEXTURE_COUNT; i++)
m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); // for (uint i = 0; i < TEXTURE_COUNT; i++)
// m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
} }
/// <summary> /// <summary>
@ -274,9 +290,6 @@ namespace OpenSim.Framework
} }
changed = true; changed = true;
// if (newface != null)
// m_log.WarnFormat("[AVATAR APPEARANCE]: index {0}, new texture id {1}",i,newface.TextureID);
} }
m_texture = textureEntry; m_texture = textureEntry;

View File

@ -990,6 +990,7 @@ namespace OpenSim.Framework.Capabilities
public void BakedTextureUploaded(UUID assetID, byte[] data) public void BakedTextureUploaded(UUID assetID, byte[] data)
{ {
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
AssetBase asset; AssetBase asset;
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
asset.Data = data; asset.Data = data;
@ -1331,6 +1332,7 @@ namespace OpenSim.Framework.Capabilities
newAssetID = UUID.Random(); newAssetID = UUID.Random();
uploaderPath = path; uploaderPath = path;
httpListener = httpServer; httpListener = httpServer;
// m_log.WarnFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
} }
/// <summary> /// <summary>
@ -1342,6 +1344,8 @@ namespace OpenSim.Framework.Capabilities
/// <returns></returns> /// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param) public string uploaderCaps(byte[] data, string path, string param)
{ {
m_log.WarnFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
string res = String.Empty; string res = String.Empty;
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
uploadComplete.new_asset = newAssetID.ToString(); uploadComplete.new_asset = newAssetID.ToString();

View File

@ -115,7 +115,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
#endregion #endregion
public bool ValidateBakedTextureCache(IClientAPI client) public bool ValidateBakedTextureCache(IClientAPI client)
{
return ValidateBakedTextureCache(client, true);
}
private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
{ {
ScenePresence sp = m_scene.GetScenePresence(client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null) if (sp == null)
@ -131,15 +137,33 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
int idx = AvatarAppearance.BAKE_INDICES[i]; int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
// if there is no texture entry, skip it
if (face == null)
continue; continue;
// if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter
// if the avatar isnt wearing a skirt) but if any of the main baked
// textures is default then the rest should be as well
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
defonly = false; // found a non-default texture reference defonly = false; // found a non-default texture reference
if (! CheckBakedTextureAsset(client,face.TextureID,idx)) if (! CheckBakedTextureAsset(client,face.TextureID,idx))
return false; {
// the asset didn't exist if we are only checking, then we found a bad
// one and we're done otherwise, ask for a rebake
if (checkonly) return false;
m_log.WarnFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID);
client.SendRebakeAvatarTextures(face.TextureID);
}
} }
m_log.WarnFormat("[AVFACTORY]: complete texture check for {0}",client.AgentId);
// If we only found default textures, then the appearance is not cached // If we only found default textures, then the appearance is not cached
return (defonly ? false : true); return (defonly ? false : true);
} }
@ -158,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return; return;
} }
// m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); m_log.WarnFormat("[AVFACTORY]: start SetAppearance for {0}",client.AgentId);
bool changed = false; bool changed = false;
@ -166,47 +190,40 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// going to be handled correctly but it does serialize the updates to the appearance // going to be handled correctly but it does serialize the updates to the appearance
lock (m_setAppearanceLock) lock (m_setAppearanceLock)
{ {
if (textureEntry != null)
{
changed = sp.Appearance.SetTextureEntries(textureEntry);
// m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
Util.FireAndForget(delegate(object o) {
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
client.SendRebakeAvatarTextures(face.TextureID);
});
}
m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
}
// Process the visual params, this may change height as well // Process the visual params, this may change height as well
if (visualParams != null) if (visualParams != null)
{ {
if (sp.Appearance.SetVisualParams(visualParams)) changed = sp.Appearance.SetVisualParams(visualParams);
{ if (sp.Appearance.AvatarHeight > 0)
changed = true; sp.SetHeight(sp.Appearance.AvatarHeight);
if (sp.Appearance.AvatarHeight > 0)
sp.SetHeight(sp.Appearance.AvatarHeight);
}
} }
// Process the baked texture array
if (textureEntry != null)
{
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
m_log.WarnFormat("[AVFACTORY]: received texture update for {0}",client.AgentId);
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
// This appears to be set only in the final stage of the appearance
// update transaction. In theory, we should be able to do an immediate
// appearance send and save here.
QueueAppearanceSave(client.AgentId);
QueueAppearanceSend(client.AgentId);
}
} }
// If something changed in the appearance then queue an appearance save // // If something changed in the appearance then queue an appearance save
if (changed) // if (changed)
QueueAppearanceSave(client.AgentId); // QueueAppearanceSave(client.AgentId);
// And always queue up an appearance update to send out // // And always queue up an appearance update to send out
QueueAppearanceSend(client.AgentId); // QueueAppearanceSend(client.AgentId);
// m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
} }
/// <summary> /// <summary>
@ -229,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
#region UpdateAppearanceTimer #region UpdateAppearanceTimer
/// <summary>
/// Queue up a request to send appearance, makes it possible to
/// accumulate changes without sending out each one separately.
/// </summary>
public void QueueAppearanceSend(UUID agentid) public void QueueAppearanceSend(UUID agentid)
{ {
// m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
@ -268,6 +289,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// Send the appearance to everyone in the scene // Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents(); sp.SendAppearanceToAllOtherAgents();
// Send animations back to the avatar as well
sp.Animator.SendAnimPack();
} }
private void HandleAppearanceSave(UUID agentid) private void HandleAppearanceSave(UUID agentid)
@ -355,7 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// operate on a copy of the appearance so we don't have to lock anything // operate on a copy of the appearance so we don't have to lock anything
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
sp.Appearance.ResetBakedTextures(); // this makes sure we don't reuse old textures if the baking takes time
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
{ {
if (wear.Type < AvatarWearable.MAX_WEARABLES) if (wear.Type < AvatarWearable.MAX_WEARABLES)

View File

@ -2773,30 +2773,44 @@ namespace OpenSim.Region.Framework.Scenes
// the inventory arrives // the inventory arrives
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
// This agent just became root. We are going to tell everyone about it. The process of bool cachedappearance = false;
// getting other avatars information was initiated in the constructor... don't do it
// again here...
SendAvatarDataToAllAgents();
// We have an appearance but we may not have the baked textures. Check the asset cache // We have an appearance but we may not have the baked textures. Check the asset cache
// to see if all the baked textures are already here. // to see if all the baked textures are already here.
if (m_scene.AvatarFactory != null) if (m_scene.AvatarFactory != null)
{ {
if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
{
// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
SendAppearanceToAgent(this);
// If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when
// the avatar finishes updating its appearance
SendAppearanceToAllOtherAgents();
}
} }
else else
{ {
m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
} }
// If we aren't using a cached appearance, then clear out the baked textures
if (! cachedappearance)
{
m_appearance.ResetBakedTextures();
if (m_scene.AvatarFactory != null)
m_scene.AvatarFactory.QueueAppearanceSave(UUID);
}
// This agent just became root. We are going to tell everyone about it. The process of
// getting other avatars information was initiated in the constructor... don't do it
// again here... this comes after the cached appearance check because the avatars
// appearance goes into the avatar update packet
SendAvatarDataToAllAgents();
// If we are using the the cached appearance then send it out to everyone
if (cachedappearance)
{
m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
SendAppearanceToAgent(this);
// If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when
// the avatar finishes updating its appearance
SendAppearanceToAllOtherAgents();
}
} }
/// <summary> /// <summary>
@ -2856,7 +2870,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Send avatar data to an agent. /// Send avatar data to an agent.
/// </summary> /// </summary>
/// <param name="avatar"></param> /// <param name="avatar"></param>
private void SendAvatarDataToAgent(ScenePresence avatar) public void SendAvatarDataToAgent(ScenePresence avatar)
{ {
// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); // m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
@ -2924,7 +2938,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Send appearance data to an agent. /// Send appearance data to an agent.
/// </summary> /// </summary>
/// <param name="avatar"></param> /// <param name="avatar"></param>
private void SendAppearanceToAgent(ScenePresence avatar) public void SendAppearanceToAgent(ScenePresence avatar)
{ {
// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);