private void RequestAgentSetAppearance()
{
AgentSetAppearancePacket set = new AgentSetAppearancePacket();
set.AgentData.AgentID = Client.Self.AgentID;
set.AgentData.SessionID = Client.Self.SessionID;
set.AgentData.SerialNum = (uint)Interlocked.Increment(ref SetAppearanceSerialNum);
// Visual params used in the agent height calculation
float agentSizeVPHeight = 0.0f;
float agentSizeVPHeelHeight = 0.0f;
float agentSizeVPPlatformHeight = 0.0f;
float agentSizeVPHeadSize = 0.5f;
float agentSizeVPLegLength = 0.0f;
float agentSizeVPNeckLength = 0.0f;
float agentSizeVPHipLength = 0.0f;
lock (Wearables)
{
#region VisualParam
int vpIndex = 0;
set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[218];
foreach (KeyValuePair<int, VisualParam> kvp in VisualParams.Params)
{
VisualParam vp = kvp.Value;
float paramValue = 0f;
bool found = false;
// Try and find this value in our collection of downloaded wearables
foreach (WearableData data in Wearables.Values)
{
if (data.Asset != null && data.Asset.Params.TryGetValue(vp.ParamID, out paramValue))
{
found = true;
break;
}
}
// Use a default value if we don't have one set for it
if (!found)
paramValue = vp.DefaultValue;
// Only Group-0 parameters are sent in AgentSetAppearance packets
if (kvp.Value.Group == 0)
{
set.VisualParam[vpIndex] = new AgentSetAppearancePacket.VisualParamBlock();
set.VisualParam[vpIndex].ParamValue = Utils.FloatToByte(paramValue, vp.MinValue, vp.MaxValue);
++vpIndex;
}
// Check if this is one of the visual params used in the agent height calculation
switch (vp.ParamID)
{
case 33:
agentSizeVPHeight = paramValue;
break;
case 198:
agentSizeVPHeelHeight = paramValue;
break;
case 503:
agentSizeVPPlatformHeight = paramValue;
break;
case 682:
agentSizeVPHeadSize = paramValue;
break;
case 692:
agentSizeVPLegLength = paramValue;
break;
case 756:
agentSizeVPNeckLength = paramValue;
break;
case 842:
agentSizeVPHipLength = paramValue;
break;
}
}
#endregion VisualParam
#region TextureEntry
Primitive.TextureEntry te = new Primitive.TextureEntry(DEFAULT_AVATAR_TEXTURE);
for (uint i = 0; i < Textures.Length; i++)
{
if (i == 0 && Client.Settings.CLIENT_IDENTIFICATION_TAG != UUID.Zero)
{
Primitive.TextureEntryFace face = te.CreateFace(i);
face.TextureID = Client.Settings.CLIENT_IDENTIFICATION_TAG;
Logger.DebugLog("Sending client identification tag: " + Client.Settings.CLIENT_IDENTIFICATION_TAG, Client);
}
else if (Textures[i].TextureID != UUID.Zero)
{
Primitive.TextureEntryFace face = te.CreateFace(i);
face.TextureID = Textures[i].TextureID;
Logger.DebugLog("Sending texture entry for " + (AvatarTextureIndex)i + " to " + Textures[i].TextureID, Client);
}
}
set.ObjectData.TextureEntry = te.GetBytes();
#endregion TextureEntry
#region WearableData
set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[BAKED_TEXTURE_COUNT];
// Build hashes for each of the bake layers from the individual components
for (int bakedIndex = 0; bakedIndex < BAKED_TEXTURE_COUNT; bakedIndex++)
{
UUID hash = UUID.Zero;
for (int wearableIndex = 0; wearableIndex < WEARABLES_PER_LAYER; wearableIndex++)
{
WearableType type = WEARABLE_BAKE_MAP[bakedIndex][wearableIndex];
WearableData wearable;
if (type != WearableType.Invalid && Wearables.TryGetValue(type, out wearable))
hash ^= wearable.AssetID;
}
if (hash != UUID.Zero)
{
// Hash with our magic value for this baked layer
hash ^= BAKED_TEXTURE_HASH[bakedIndex];
}
// Tell the server what cached texture assetID to use for each bake layer
set.WearableData[bakedIndex] = new AgentSetAppearancePacket.WearableDataBlock();
set.WearableData[bakedIndex].TextureIndex = BakeIndexToTextureIndex[bakedIndex];
set.WearableData[bakedIndex].CacheID = hash;
Logger.DebugLog("Sending TextureIndex " + (BakeType)bakedIndex + " with CacheID " + hash, Client);
}
#endregion WearableData
#region Agent Size
// Takes into account the Shoe Heel/Platform offsets but not the HeadSize offset. Seems to work.
double agentSizeBase = 1.706;
// The calculation for the HeadSize scalar may be incorrect, but it seems to work
double agentHeight = agentSizeBase + (agentSizeVPLegLength * .1918) + (agentSizeVPHipLength * .0375) +
(agentSizeVPHeight * .12022) + (agentSizeVPHeadSize * .01117) + (agentSizeVPNeckLength * .038) +
(agentSizeVPHeelHeight * .08) + (agentSizeVPPlatformHeight * .07);
set.AgentData.Size = new Vector3(0.45f, 0.6f, (float)agentHeight);
#endregion Agent Size
}
Client.Network.SendPacket(set);
Logger.DebugLog("Send AgentSetAppearance packet");
}