public void TextureEntry() { LLObject.TextureEntry te = new LLObject.TextureEntry(UUID.Random()); LLObject.TextureEntryFace face = te.CreateFace(0); face.Bump = Bumpiness.Concrete; face.Fullbright = true; face.MediaFlags = true; face.OffsetU = 0.5f; face.OffsetV = -0.5f; face.RepeatU = 3.0f; face.RepeatV = 4.0f; face.RGBA = new Color4(0f, 0.25f, 0.75f, 1f); face.Rotation = 1.5f; face.Shiny = Shininess.Medium; face.TexMapType = MappingType.Planar; face.TextureID = UUID.Random(); byte[] teBytes = te.ToBytes(); LLObject.TextureEntry te2 = new LLObject.TextureEntry(teBytes, 0, teBytes.Length); byte[] teBytes2 = te2.ToBytes(); Assert.IsTrue(teBytes.Length == teBytes2.Length); for (int i = 0; i < teBytes.Length; i++) { Assert.IsTrue(teBytes[i] == teBytes2[i], "Byte " + i + " is not equal"); } }
private void SendAgentSetAppearance() { AgentSetAppearancePacket set = new AgentSetAppearancePacket(); set.AgentData.AgentID = Client.Self.AgentID; set.AgentData.SessionID = Client.Self.SessionID; set.AgentData.SerialNum = SetAppearanceSerialNum++; set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[218]; 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.Dictionary) { // Only for debugging output int count = 0, vpIndex = 0; // Build the visual param array foreach (KeyValuePair<int, VisualParam> kvp in VisualParams.Params) { VisualParam vp = kvp.Value; // Only Group-0 parameters are sent in AgentSetAppearance packets if (vp.Group == 0) { set.VisualParam[vpIndex] = new AgentSetAppearancePacket.VisualParamBlock(); // Try and find this value in our collection of downloaded wearables foreach (WearableData data in Wearables.Dictionary.Values) { if (data.Asset != null && data.Asset.Params.ContainsKey(vp.ParamID)) { set.VisualParam[vpIndex].ParamValue = Helpers.FloatToByte(data.Asset.Params[vp.ParamID], vp.MinValue, vp.MaxValue); count++; switch (vp.ParamID) { case 33: AgentSizeVPHeight = data.Asset.Params[vp.ParamID]; break; case 198: AgentSizeVPHeelHeight = data.Asset.Params[vp.ParamID]; break; case 503: AgentSizeVPPlatformHeight = data.Asset.Params[vp.ParamID]; break; case 682: AgentSizeVPHeadSize = data.Asset.Params[vp.ParamID]; break; case 692: AgentSizeVPLegLength = data.Asset.Params[vp.ParamID]; break; case 756: AgentSizeVPNeckLength = data.Asset.Params[vp.ParamID]; break; case 842: AgentSizeVPHipLength = data.Asset.Params[vp.ParamID]; break; } break; } } ++vpIndex; } } // Build the texture entry for our agent LLObject.TextureEntry te = new LLObject.TextureEntry(DEFAULT_AVATAR_TEXTURE); // Put our AgentTextures array in to TextureEntry lock (AgentTextures) { for (uint i = 0; i < AgentTextures.Length; i++) { if (AgentTextures[i] != UUID.Zero) { LLObject.TextureEntryFace face = te.CreateFace(i); face.TextureID = AgentTextures[i]; } } } foreach (WearableData data in Wearables.Dictionary.Values) { if (data.Asset != null) { foreach (KeyValuePair<TextureIndex, UUID> texture in data.Asset.Textures) { LLObject.TextureEntryFace face = te.CreateFace((uint)texture.Key); face.TextureID = texture.Value; Logger.DebugLog("Setting agent texture " + ((TextureIndex)texture.Key).ToString() + " to " + texture.Value.ToString(), Client); } } } // Set the packet TextureEntry set.ObjectData.TextureEntry = te.ToBytes(); } // FIXME: Our hackish algorithm is making squished avatars. See // http://www.OpenMetaverse.org/wiki/Agent_Size for discussion of the correct algorithm //float height = Helpers.ByteToFloat(set.VisualParam[33].ParamValue, VisualParams.Params[33].MinValue, // VisualParams.Params[33].MaxValue); // Takes into account the Shoe Heel/Platform offsets but not the Head Size Offset. But seems to work. double AgentSizeBase = 1.706; // The calculation for the Head Size scalar may be incorrect. But 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); // TODO: Account for not having all the textures baked yet 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 = new UUID(); for (int wearableIndex = 0; wearableIndex < WEARABLES_PER_LAYER; wearableIndex++) { WearableType type = WEARABLE_BAKE_MAP[bakedIndex][wearableIndex]; UUID assetID = GetWearableAsset(type); // Build a hash of all the texture asset IDs in this baking layer if (assetID != UUID.Zero) hash ^= assetID; } if (hash != UUID.Zero) { // Hash with our secret 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 = (byte)bakedIndex; set.WearableData[bakedIndex].CacheID = hash; } // Finally, send the packet Client.Network.SendPacket(set); }