This is an experimental patch that adds support for comparing texture
hashes for the purpose of accurately responding to AgentTextureCached packets. There is a change to IClientAPI to report the wearbles hashes that come in through the SetAppearance packet. Added storage of the texture hashes in the appearance. While these are added to the Pack/Unpack (with support for missing values) routines (which means Simian will store them properly), they are not currently persisted in Robust.user_profiles
parent
440905ad14
commit
681fbda4b6
|
@ -53,6 +53,7 @@ namespace OpenSim.Framework
|
||||||
protected AvatarWearable[] m_wearables;
|
protected AvatarWearable[] m_wearables;
|
||||||
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
|
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
|
||||||
protected float m_avatarHeight = 0;
|
protected float m_avatarHeight = 0;
|
||||||
|
protected UUID[] m_texturehashes;
|
||||||
|
|
||||||
public virtual int Serial
|
public virtual int Serial
|
||||||
{
|
{
|
||||||
|
@ -98,6 +99,8 @@ namespace OpenSim.Framework
|
||||||
SetDefaultParams();
|
SetDefaultParams();
|
||||||
SetHeight();
|
SetHeight();
|
||||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
|
|
||||||
|
ResetTextureHashes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance(OSDMap map)
|
public AvatarAppearance(OSDMap map)
|
||||||
|
@ -108,32 +111,6 @@ namespace OpenSim.Framework
|
||||||
SetHeight();
|
SetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
|
||||||
{
|
|
||||||
// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
|
|
||||||
|
|
||||||
m_serial = 0;
|
|
||||||
|
|
||||||
if (wearables != null)
|
|
||||||
m_wearables = wearables;
|
|
||||||
else
|
|
||||||
SetDefaultWearables();
|
|
||||||
|
|
||||||
if (textureEntry != null)
|
|
||||||
m_texture = textureEntry;
|
|
||||||
else
|
|
||||||
SetDefaultTexture();
|
|
||||||
|
|
||||||
if (visualParams != null)
|
|
||||||
m_visualparams = visualParams;
|
|
||||||
else
|
|
||||||
SetDefaultParams();
|
|
||||||
|
|
||||||
SetHeight();
|
|
||||||
|
|
||||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
|
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -151,6 +128,8 @@ namespace OpenSim.Framework
|
||||||
SetHeight();
|
SetHeight();
|
||||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
|
|
||||||
|
ResetTextureHashes();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +145,10 @@ namespace OpenSim.Framework
|
||||||
SetWearable(i,appearance.Wearables[i]);
|
SetWearable(i,appearance.Wearables[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||||
|
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
|
m_texturehashes[i] = new UUID(appearance.m_texturehashes[i]);
|
||||||
|
|
||||||
m_texture = null;
|
m_texture = null;
|
||||||
if (appearance.Texture != null)
|
if (appearance.Texture != null)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +183,37 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetTextureHashes()
|
||||||
|
{
|
||||||
|
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||||
|
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
|
m_texturehashes[i] = UUID.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID GetTextureHash(int textureIndex)
|
||||||
|
{
|
||||||
|
return m_texturehashes[NormalizeBakedTextureIndex(textureIndex)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTextureHash(int textureIndex, UUID textureHash)
|
||||||
|
{
|
||||||
|
m_texturehashes[NormalizeBakedTextureIndex(textureIndex)] = new UUID(textureHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normalizes the texture index to the actual bake index, this is done to
|
||||||
|
/// accommodate older viewers that send the BAKE_INDICES index rather than
|
||||||
|
/// the actual texture index
|
||||||
|
/// </summary>
|
||||||
|
private int NormalizeBakedTextureIndex(int textureIndex)
|
||||||
|
{
|
||||||
|
// Earlier viewer send the index into the baked index array, just trying to be careful here
|
||||||
|
if (textureIndex < BAKE_INDICES.Length)
|
||||||
|
return BAKE_INDICES[textureIndex];
|
||||||
|
|
||||||
|
return textureIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearWearables()
|
public void ClearWearables()
|
||||||
{
|
{
|
||||||
m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
|
m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
|
||||||
|
@ -223,12 +237,7 @@ namespace OpenSim.Framework
|
||||||
m_serial = 0;
|
m_serial = 0;
|
||||||
|
|
||||||
SetDefaultTexture();
|
SetDefaultTexture();
|
||||||
|
ResetTextureHashes();
|
||||||
//for (int i = 0; i < BAKE_INDICES.Length; i++)
|
|
||||||
// {
|
|
||||||
// int idx = BAKE_INDICES[i];
|
|
||||||
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SetDefaultParams()
|
protected virtual void SetDefaultParams()
|
||||||
|
@ -598,6 +607,12 @@ namespace OpenSim.Framework
|
||||||
data["serial"] = OSD.FromInteger(m_serial);
|
data["serial"] = OSD.FromInteger(m_serial);
|
||||||
data["height"] = OSD.FromReal(m_avatarHeight);
|
data["height"] = OSD.FromReal(m_avatarHeight);
|
||||||
|
|
||||||
|
// Hashes
|
||||||
|
OSDArray hashes = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
|
||||||
|
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
|
hashes.Add(OSD.FromUUID(m_texturehashes[i]));
|
||||||
|
data["hashes"] = hashes;
|
||||||
|
|
||||||
// Wearables
|
// Wearables
|
||||||
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
|
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
|
||||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||||
|
@ -642,6 +657,25 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Hashes
|
||||||
|
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||||
|
if ((data != null) && (data["hashes"] != null) && (data["hashes"]).Type == OSDType.Array)
|
||||||
|
{
|
||||||
|
OSDArray hashes = (OSDArray)(data["hashes"]);
|
||||||
|
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
|
{
|
||||||
|
UUID hashID = UUID.Zero;
|
||||||
|
if (i < hashes.Count && hashes[i] != null)
|
||||||
|
hashID = hashes[i].AsUUID();
|
||||||
|
m_texturehashes[i] = hashID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
|
m_texturehashes[i] = UUID.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
// Wearables
|
// Wearables
|
||||||
SetDefaultWearables();
|
SetDefaultWearables();
|
||||||
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
|
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
|
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
|
||||||
|
|
||||||
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams);
|
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> cachedTextureData);
|
||||||
|
|
||||||
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
||||||
|
|
||||||
|
|
|
@ -6214,7 +6214,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (appear.ObjectData.TextureEntry.Length > 1)
|
if (appear.ObjectData.TextureEntry.Length > 1)
|
||||||
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
|
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
|
||||||
|
|
||||||
handlerSetAppearance(sender, te, visualparams);
|
List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>();
|
||||||
|
for (int i = 0; i < appear.WearableData.Length; i++)
|
||||||
|
{
|
||||||
|
CachedTextureRequestArg arg = new CachedTextureRequestArg();
|
||||||
|
arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
|
||||||
|
arg.WearableHashID = appear.WearableData[i].CacheID;
|
||||||
|
hashes.Add(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerSetAppearance(sender, te, visualparams, hashes);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -11487,12 +11496,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
requestArgs.Add(arg);
|
requestArgs.Add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
|
try
|
||||||
if (handlerCachedTextureRequest != null)
|
|
||||||
{
|
{
|
||||||
handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
|
CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
|
||||||
|
if (handlerCachedTextureRequest != null)
|
||||||
|
{
|
||||||
|
handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
||||||
{
|
{
|
||||||
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
|
DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -158,9 +158,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>());
|
||||||
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
}
|
||||||
// sp.Name, textureEntry, visualParams);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set appearance data (texture asset IDs and slider settings)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sp"></param>
|
||||||
|
/// <param name="texture"></param>
|
||||||
|
/// <param name="visualParam"></param>
|
||||||
|
protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
||||||
|
// sp.Name, textureEntry, visualParams);
|
||||||
|
|
||||||
// TODO: This is probably not necessary any longer, just assume the
|
// TODO: This is probably not necessary any longer, just assume the
|
||||||
// textureEntry set implies that the appearance transaction is complete
|
// textureEntry set implies that the appearance transaction is complete
|
||||||
|
@ -190,18 +201,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
// Process the baked texture array
|
// Process the baked texture array
|
||||||
if (textureEntry != null)
|
if (textureEntry != null)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
||||||
|
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
|
||||||
|
|
||||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||||
|
|
||||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||||
|
|
||||||
// If bake textures are missing and this is not an NPC, request a rebake from client
|
// If bake textures are missing and this is not an NPC, request a rebake from client
|
||||||
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
|
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
|
||||||
RequestRebake(sp, true);
|
RequestRebake(sp, true);
|
||||||
|
|
||||||
|
// Save the wearble hashes in the appearance
|
||||||
|
sp.Appearance.ResetTextureHashes();
|
||||||
|
foreach (CachedTextureRequestArg arg in hashes)
|
||||||
|
sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
|
||||||
|
|
||||||
// This appears to be set only in the final stage of the appearance
|
// 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
|
// update transaction. In theory, we should be able to do an immediate
|
||||||
// appearance send and save here.
|
// appearance send and save here.
|
||||||
|
@ -235,13 +250,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
public bool SendAppearance(UUID agentId)
|
public bool SendAppearance(UUID agentId)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
||||||
|
|
||||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
// This is expected if the user has gone away.
|
// This is expected if the user has gone away.
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="agentId"></param>
|
/// <param name="agentId"></param>
|
||||||
public void QueueAppearanceSend(UUID agentid)
|
public void QueueAppearanceSend(UUID agentid)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
|
// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
|
||||||
|
|
||||||
// 10000 ticks per millisecond, 1000 milliseconds per second
|
// 10000 ticks per millisecond, 1000 milliseconds per second
|
||||||
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
|
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
|
||||||
|
@ -331,7 +346,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
public void QueueAppearanceSave(UUID agentid)
|
public void QueueAppearanceSave(UUID agentid)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
|
// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
|
||||||
|
|
||||||
// 10000 ticks per millisecond, 1000 milliseconds per second
|
// 10000 ticks per millisecond, 1000 milliseconds per second
|
||||||
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
|
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
|
||||||
|
@ -356,9 +371,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
if (face == null)
|
if (face == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
||||||
// face.TextureID, idx, client.Name, client.AgentId);
|
// face.TextureID, idx, client.Name, client.AgentId);
|
||||||
|
|
||||||
// if the texture is one of the "defaults" then skip it
|
// if the texture is one of the "defaults" then skip it
|
||||||
// this should probably be more intelligent (skirt texture doesnt matter
|
// this should probably be more intelligent (skirt texture doesnt matter
|
||||||
|
@ -373,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
|
// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -392,9 +407,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
if (face == null)
|
if (face == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
||||||
// face.TextureID, idx, client.Name, client.AgentId);
|
// face.TextureID, idx, client.Name, client.AgentId);
|
||||||
|
|
||||||
// if the texture is one of the "defaults" then skip it
|
// if the texture is one of the "defaults" then skip it
|
||||||
// this should probably be more intelligent (skirt texture doesnt matter
|
// this should probably be more intelligent (skirt texture doesnt matter
|
||||||
|
@ -458,9 +473,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
if (bakeType == BakeType.Unknown)
|
if (bakeType == BakeType.Unknown)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
||||||
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
||||||
|
|
||||||
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
|
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
|
||||||
Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
|
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
|
||||||
UUID avatarID = kvp.Key;
|
UUID avatarID = kvp.Key;
|
||||||
long sendTime = kvp.Value;
|
long sendTime = kvp.Value;
|
||||||
|
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
|
// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
|
||||||
|
|
||||||
if (sendTime < now)
|
if (sendTime < now)
|
||||||
{
|
{
|
||||||
|
@ -530,11 +545,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
// This is expected if the user has gone away.
|
// This is expected if the user has gone away.
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
|
// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
|
||||||
|
|
||||||
// This could take awhile since it needs to pull inventory
|
// This could take awhile since it needs to pull inventory
|
||||||
// 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
|
// 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
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="texture"></param>
|
/// <param name="texture"></param>
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
|
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
|
||||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
SetAppearance(sp, textureEntry, visualParams);
|
DoSetAppearance(sp, textureEntry, visualParams, hashes);
|
||||||
else
|
else
|
||||||
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
|
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
|
||||||
}
|
}
|
||||||
|
@ -684,7 +699,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="cachedTextureRequest"></param>
|
/// <param name="cachedTextureRequest"></param>
|
||||||
private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
|
private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
|
// m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
|
||||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||||
|
|
||||||
List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
|
List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
|
||||||
|
@ -695,23 +710,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
if (m_reusetextures)
|
if (m_reusetextures)
|
||||||
{
|
{
|
||||||
// this is the most insanely dumb way to do this... however it seems to
|
if (sp.Appearance.GetTextureHash(index) == request.WearableHashID)
|
||||||
// actually work. if the appearance has been reset because wearables have
|
{
|
||||||
// changed then the texture entries are zero'd out until the bakes are
|
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
|
||||||
// uploaded. on login, if the textures exist in the cache (eg if you logged
|
if (face != null)
|
||||||
// into the simulator recently, then the appearance will pull those and send
|
texture = face.TextureID;
|
||||||
// them back in the packet and you won't have to rebake. if the textures aren't
|
}
|
||||||
// in the cache then the intial makeroot() call in scenepresence will zero
|
else
|
||||||
// them out.
|
{
|
||||||
//
|
// We know that that hash is wrong, null it out
|
||||||
// a better solution (though how much better is an open question) is to
|
// and wait for the setappearance call
|
||||||
// store the hashes in the appearance and compare them. Thats's coming.
|
sp.Appearance.SetTextureHash(index,UUID.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
|
// m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID);
|
||||||
if (face != null)
|
|
||||||
texture = face.TextureID;
|
|
||||||
|
|
||||||
// m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedTextureResponseArg response = new CachedTextureResponseArg();
|
CachedTextureResponseArg response = new CachedTextureResponseArg();
|
||||||
|
|
|
@ -907,7 +907,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
// Mimicking LLClientView which gets always set appearance from client.
|
// Mimicking LLClientView which gets always set appearance from client.
|
||||||
AvatarAppearance appearance;
|
AvatarAppearance appearance;
|
||||||
m_scene.GetAvatarAppearance(this, out appearance);
|
m_scene.GetAvatarAppearance(this, out appearance);
|
||||||
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone());
|
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
|
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
|
||||||
|
|
Loading…
Reference in New Issue