aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/AvatarAppearance.cs
diff options
context:
space:
mode:
authorMaster ScienceSim2010-10-20 16:17:54 -0700
committerMaster ScienceSim2010-10-20 16:17:54 -0700
commitb1c8d0588829dfa76f89460eeb8406d9c4fc479f (patch)
tree463cbb0bf2eab5c7e7f98ebdc0dc7113dea56688 /OpenSim/Framework/AvatarAppearance.cs
parentMerge branch 'master' of /var/git/opensim/ (diff)
downloadopensim-SC_OLD-b1c8d0588829dfa76f89460eeb8406d9c4fc479f.zip
opensim-SC_OLD-b1c8d0588829dfa76f89460eeb8406d9c4fc479f.tar.gz
opensim-SC_OLD-b1c8d0588829dfa76f89460eeb8406d9c4fc479f.tar.bz2
opensim-SC_OLD-b1c8d0588829dfa76f89460eeb8406d9c4fc479f.tar.xz
Major refactoring of appearance handling.
AvatarService -- add two new methods, GetAppearance and SetAppearance to get around the lossy encoding in AvatarData. Preseve the old functions to avoid changing the behavior for ROBUST services. AvatarAppearance -- major refactor, moved the various encoding methods used by AgentCircuitData, ClientAgentUpdate and ScenePresence into one location. Changed initialization. AvatarAttachments -- added a class specifically to handle attachments in preparation for additional functionality that will be needed for viewer 2. AvatarFactory -- removed a number of unused or methods duplicated in other locations. Moved in all appearance event handling from ScenePresence. Required a change to IClientAPI that propogated throughout all the IClientAPI implementations.
Diffstat (limited to 'OpenSim/Framework/AvatarAppearance.cs')
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs839
1 files changed, 403 insertions, 436 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 5da8ba1..55646dd 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,9 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using OpenMetaverse; 32using OpenMetaverse;
33using OpenMetaverse.StructuredData;
34using log4net;
32 35
33namespace OpenSim.Framework 36namespace OpenSim.Framework
34{ 37{
@@ -37,48 +40,26 @@ namespace OpenSim.Framework
37 /// </summary> 40 /// </summary>
38 public class AvatarAppearance 41 public class AvatarAppearance
39 { 42 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 // these are guessed at by the list here -
43 // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll
44 // correct them over time for when were are wrong.
45 public readonly static int BODY = 0;
46 public readonly static int SKIN = 1;
47 public readonly static int HAIR = 2;
48 public readonly static int EYES = 3;
49 public readonly static int SHIRT = 4;
50 public readonly static int PANTS = 5;
51 public readonly static int SHOES = 6;
52 public readonly static int SOCKS = 7;
53 public readonly static int JACKET = 8;
54 public readonly static int GLOVES = 9;
55 public readonly static int UNDERSHIRT = 10;
56 public readonly static int UNDERPANTS = 11;
57 public readonly static int SKIRT = 12;
58
59 private readonly static int MAX_WEARABLES = 13;
60
61 private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
62 private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
63 private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
64 private static UUID SKIN_ITEM = new UUID("77c41e39-38f9-f75a-024e-585989bfabc9");
65 private static UUID SHIRT_ASSET = new UUID("00000000-38f9-1111-024e-222222111110");
66 private static UUID SHIRT_ITEM = new UUID("77c41e39-38f9-f75a-0000-585989bf0000");
67 private static UUID PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120");
68 private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111");
69 private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
70 private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66");
71 44
72 public readonly static int VISUALPARAM_COUNT = 218; 45 public readonly static int VISUALPARAM_COUNT = 218;
73 46
47 public readonly static int TEXTURE_COUNT = 21;
48
74 protected UUID m_owner; 49 protected UUID m_owner;
50 protected int m_serial = 1;
51 protected byte[] m_visualparams;
52 protected Primitive.TextureEntry m_texture;
53 protected AvatarWearable[] m_wearables;
54 protected Dictionary<int, AvatarAttachment> m_attachments;
55 protected float m_avatarHeight = 0;
56 protected float m_hipOffset = 0;
75 57
76 public virtual UUID Owner 58 public virtual UUID Owner
77 { 59 {
78 get { return m_owner; } 60 get { return m_owner; }
79 set { m_owner = value; } 61 set { m_owner = value; }
80 } 62 }
81 protected int m_serial = 1;
82 63
83 public virtual int Serial 64 public virtual int Serial
84 { 65 {
@@ -86,15 +67,17 @@ namespace OpenSim.Framework
86 set { m_serial = value; } 67 set { m_serial = value; }
87 } 68 }
88 69
89 protected byte[] m_visualparams;
90
91 public virtual byte[] VisualParams 70 public virtual byte[] VisualParams
92 { 71 {
93 get { return m_visualparams; } 72 get { return m_visualparams; }
94 set { m_visualparams = value; } 73 set { m_visualparams = value; }
95 } 74 }
96 75
97 protected AvatarWearable[] m_wearables; 76 public virtual Primitive.TextureEntry Texture
77 {
78 get { return m_texture; }
79 set { m_texture = value; }
80 }
98 81
99 public virtual AvatarWearable[] Wearables 82 public virtual AvatarWearable[] Wearables
100 { 83 {
@@ -102,287 +85,363 @@ namespace OpenSim.Framework
102 set { m_wearables = value; } 85 set { m_wearables = value; }
103 } 86 }
104 87
88 public virtual Dictionary<int, AvatarAttachment> Attachments
89 {
90 get { return m_attachments; }
91 }
92
105 public virtual UUID BodyItem { 93 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 94 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 95 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 96 }
109 97
110 public virtual UUID BodyAsset { 98 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 99 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 100 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 101 }
114 102
115 public virtual UUID SkinItem { 103 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 104 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 105 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 106 }
119 107
120 public virtual UUID SkinAsset { 108 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 109 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 110 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 111 }
124 112
125 public virtual UUID HairItem { 113 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 114 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 115 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 116 }
129 117
130 public virtual UUID HairAsset { 118 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 119 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 120 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 121 }
134 122
135 public virtual UUID EyesItem { 123 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 124 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 125 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 126 }
139 127
140 public virtual UUID EyesAsset { 128 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 129 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 130 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 131 }
144 132
145 public virtual UUID ShirtItem { 133 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 134 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 135 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 136 }
149 137
150 public virtual UUID ShirtAsset { 138 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 139 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 140 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 141 }
154 142
155 public virtual UUID PantsItem { 143 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 144 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 145 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 146 }
159 147
160 public virtual UUID PantsAsset { 148 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 149 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 150 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 151 }
164 152
165 public virtual UUID ShoesItem { 153 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 154 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 155 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 156 }
169 157
170 public virtual UUID ShoesAsset { 158 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 159 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 160 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 161 }
174 162
175 public virtual UUID SocksItem { 163 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 164 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 165 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 166 }
179 167
180 public virtual UUID SocksAsset { 168 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 169 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 170 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 171 }
184 172
185 public virtual UUID JacketItem { 173 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 174 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 175 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 176 }
189 177
190 public virtual UUID JacketAsset { 178 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 179 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 180 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 181 }
194 182
195 public virtual UUID GlovesItem { 183 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 184 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 185 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 186 }
199 187
200 public virtual UUID GlovesAsset { 188 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 189 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 190 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 191 }
204 192
205 public virtual UUID UnderShirtItem { 193 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 194 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 195 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 196 }
209 197
210 public virtual UUID UnderShirtAsset { 198 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 199 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 200 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 201 }
214 202
215 public virtual UUID UnderPantsItem { 203 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 204 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 205 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 206 }
219 207
220 public virtual UUID UnderPantsAsset { 208 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 209 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 210 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 211 }
224 212
225 public virtual UUID SkirtItem { 213 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 214 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 215 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 216 }
229 217
230 public virtual UUID SkirtAsset { 218 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 219 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 220 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 } 221 }
234 222
235 public virtual void SetDefaultWearables() 223 public virtual float AvatarHeight
236 { 224 {
237 m_wearables[BODY].AssetID = BODY_ASSET; 225 get { return m_avatarHeight; }
238 m_wearables[BODY].ItemID = BODY_ITEM; 226 set { m_avatarHeight = value; }
239 m_wearables[SKIN].AssetID = SKIN_ASSET;
240 m_wearables[SKIN].ItemID = SKIN_ITEM;
241 m_wearables[HAIR].AssetID = HAIR_ASSET;
242 m_wearables[HAIR].ItemID = HAIR_ITEM;
243 m_wearables[SHIRT].AssetID = SHIRT_ASSET;
244 m_wearables[SHIRT].ItemID = SHIRT_ITEM;
245 m_wearables[PANTS].AssetID = PANTS_ASSET;
246 m_wearables[PANTS].ItemID = PANTS_ITEM;
247 } 227 }
248 228
249 public virtual void ClearWearables() 229 public virtual float HipOffset
250 { 230 {
251 for (int i = 0; i < 13; i++) 231 get { return m_hipOffset; }
252 {
253 m_wearables[i].AssetID = UUID.Zero;
254 m_wearables[i].ItemID = UUID.Zero;
255 }
256 } 232 }
257 233
258 public virtual void SetDefaultParams(byte[] vparams) 234 public AvatarAppearance() : this(UUID.Zero) {}
235
236 public AvatarAppearance(UUID owner)
259 { 237 {
260 // TODO: Figure out better values then 'fat scientist 150' or 'alien 0' 238// DEBUG ON
261 for (int i = 0; i < VISUALPARAM_COUNT; i++) 239 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
262 { 240// DEBUG OFF
263 vparams[i] = 150; 241 m_serial = 0;
264 } 242 m_owner = owner;
243
244 SetDefaultWearables();
245 SetDefaultTexture();
246 SetDefaultParams();
247 SetHeight();
248
249 m_attachments = new Dictionary<int, AvatarAttachment>();
265 } 250 }
251
252 public AvatarAppearance(UUID avatarID, OSDMap map)
253 {
254// DEBUG ON
255 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
256// DEBUG OFF
257 m_owner = avatarID;
258 Unpack(map);
259 SetHeight();
260 }
261
262 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
263 {
264// DEBUG ON
265 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
266// DEBUG OFF
267 m_serial = 1;
268 m_owner = avatarID;
266 269
267 protected Primitive.TextureEntry m_texture; 270 if (wearables != null)
271 m_wearables = wearables;
272 else
273 SetDefaultWearables();
274
275 if (textureEntry != null)
276 m_texture = textureEntry;
277 else
278 SetDefaultTexture();
268 279
269 public virtual Primitive.TextureEntry Texture 280 if (visualParams != null)
270 { 281 m_visualparams = visualParams;
271 get { return m_texture; } 282 else
272 set { m_texture = value; } 283 SetDefaultParams();
284
285 SetHeight();
286
287 m_attachments = new Dictionary<int, AvatarAttachment>();
273 } 288 }
274 289
275 protected float m_avatarHeight = 0; 290 public AvatarAppearance(AvatarAppearance appearance)
276 protected float m_hipOffset = 0; 291 {
292// DEBUG ON
293 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
294// DEBUG OFF
295 if (appearance == null)
296 {
297 m_serial = 0;
298 m_owner = UUID.Zero;
277 299
278 public virtual float AvatarHeight 300 SetDefaultWearables();
301 SetDefaultTexture();
302 SetDefaultParams();
303 SetHeight();
304
305 m_attachments = new Dictionary<int, AvatarAttachment>();
306
307 return;
308 }
309
310 m_serial = appearance.Serial;
311 m_owner = appearance.Owner;
312
313 m_wearables = null;
314 if (appearance.Wearables != null)
315 {
316 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
317 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
318 SetWearable(i,appearance.Wearables[i]);
319 }
320
321 m_texture = null;
322 if (appearance.Texture != null)
323 {
324 byte[] tbytes = appearance.Texture.GetBytes();
325 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
326 }
327
328 m_visualparams = null;
329 if (appearance.VisualParams != null)
330 m_visualparams = (byte[])appearance.VisualParams.Clone();
331
332 m_attachments = new Dictionary<int, AvatarAttachment>();
333 foreach (KeyValuePair<int, AvatarAttachment> kvp in appearance.Attachments)
334 m_attachments[kvp.Key] = new AvatarAttachment(kvp.Value);
335 }
336
337 protected virtual void SetDefaultWearables()
279 { 338 {
280 get { return m_avatarHeight; } 339 m_wearables = AvatarWearable.DefaultWearables;
281 set { m_avatarHeight = value; }
282 } 340 }
283 341
284 public virtual float HipOffset 342 protected virtual void SetDefaultParams()
285 { 343 {
286 get { return m_hipOffset; } 344 m_visualparams = new byte[VISUALPARAM_COUNT];
345 for (int i = 0; i < VISUALPARAM_COUNT; i++)
346 {
347 m_visualparams[i] = 150;
348 }
287 } 349 }
288 350
289 //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues 351 protected virtual void SetDefaultTexture()
290 /*
291 public void BuildVisualParamEnum()
292 { 352 {
293 Dictionary<string, int> IndexedParams = new Dictionary<string, int>(); 353 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
294 int vpIndex = 0; 354 // The initialization of these seems to force a rebake regardless of whether it is needed
295 IndexedParams = new Dictionary<string, int>(); 355 // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
296 356 // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
297 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 357 // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
358 // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
359 // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
360 // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
361 // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
362 }
298 363
299 sb.Append("public enum VPElement: int\n"); 364 /// <summary>
300 sb.Append("{\n"); 365 /// Set up appearance textures.
301 foreach (KeyValuePair<int, VisualParam> kvp in OpenMetaverse.VisualParams.Params) 366 /// Returns boolean that indicates whether the new entries actually change the
367 /// existing values.
368 /// </summary>
369 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
370 {
371 if (textureEntry == null)
372 return false;
373
374 // There are much simpler versions of this copy that could be
375 // made. We determine if any of the textures actually
376 // changed to know if the appearance should be saved later
377 bool changed = false;
378 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
302 { 379 {
303 VisualParam vp = kvp.Value; 380 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
304 381 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
305 // Only Group-0 parameters are sent in AgentSetAppearance packets
306 if (kvp.Value.Group == 0)
307 {
308 382
309 if (!IndexedParams.ContainsKey(vp.Name)) 383 if (newface == null)
310 { 384 {
311 385 if (oldface == null) continue;
312 if (vp.Label.Length > 0 || vp.LabelMin.Length > 0 || vp.LabelMax.Length > 0)
313 {
314
315 sb.Append("/// <summary>\n");
316 if (vp.LabelMin.Length > 0 && vp.LabelMax.Length > 0)
317 sb.Append(string.Format("/// {0} - {1} 0--+255 {2}\n", vp.Label, vp.LabelMin,
318 vp.LabelMax));
319
320 else
321 sb.Append(string.Format("/// {0}\n", vp.Label));
322
323 sb.Append("/// </summary>\n");
324 }
325 sb.Append(string.Format(" {0}_{1} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"),vpIndex));
326
327 IndexedParams.Add(vp.Name, vpIndex++);
328 }
329 else
330 {
331 sb.Append(string.Format(" {0}_{1}_{2} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"), vpIndex));
332 vpIndex++;
333 //int i = 0;
334 }
335 } 386 }
336 if (vpIndex < 217)
337 sb.Append(",\n");
338 else 387 else
339 sb.Append("\n"); 388 {
389 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
390 }
340 391
392 m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
393 changed = true;
394// DEBUG ON
395 if (newface != null)
396 m_log.WarnFormat("[SCENEPRESENCE] index {0}, new texture id {1}",i,newface.TextureID);
397// DEBUG OFF
341 } 398 }
342 sb.Append("}\n");
343 399
400 return changed;
344 } 401 }
345 */ 402
346 403 /// <summary>
347 public AvatarAppearance() : this(UUID.Zero) {} 404 /// Set up visual parameters for the avatar and refresh the avatar height
348 405 /// Returns boolean that indicates whether the new entries actually change the
349 public AvatarAppearance(UUID owner) 406 /// existing values.
407 /// </summary>
408 public virtual bool SetVisualParams(byte[] visualParams)
350 { 409 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 410 if (visualParams == null)
352 for (int i = 0; i < MAX_WEARABLES; i++) 411 return false;
412
413 // There are much simpler versions of this copy that could be
414 // made. We determine if any of the visual parameters actually
415 // changed to know if the appearance should be saved later
416 bool changed = false;
417 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
353 { 418 {
354 // this makes them all null 419 if (visualParams[i] != m_visualparams[i])
355 m_wearables[i] = new AvatarWearable(); 420 {
421// DEBUG ON
422 m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
423 i,m_visualparams[i],visualParams[i]);
424// DEBUG OFF
425 m_visualparams[i] = visualParams[i];
426 changed = true;
427 }
356 } 428 }
357 m_serial = 0; 429
358 m_owner = owner; 430 // Reset the height if the visual parameters actually changed
359 //BuildVisualParamEnum() 431 if (changed)
360 m_visualparams = new byte[VISUALPARAM_COUNT]; 432 SetHeight();
361 // This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist 433
362 SetDefaultParams(m_visualparams); 434 return changed;
363 SetDefaultWearables();
364 m_texture = GetDefaultTexture();
365 } 435 }
366 436
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 437 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
368 { 438 {
369 m_owner = avatarID; 439 SetTextureEntries(textureEntry);
370 m_serial = 1; 440 SetVisualParams(visualParams);
371 m_wearables = wearables;
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 441 }
375 442
376 /// <summary> 443 public virtual void SetHeight()
377 /// Set up appearance textures and avatar parameters, including a height calculation
378 /// </summary>
379 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
380 { 444 {
381 if (textureEntry != null)
382 m_texture = textureEntry;
383 if (visualParams != null)
384 m_visualparams = visualParams;
385
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 445 m_avatarHeight = 1.23077f // Shortest possible avatar height
387 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height 446 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
388 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size 447 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
@@ -390,217 +449,63 @@ namespace OpenSim.Framework
390 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height 449 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
391 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height 450 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
392 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length 451 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
452
393 m_hipOffset = (((1.23077f // Half of avatar 453 m_hipOffset = (((1.23077f // Half of avatar
394 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height 454 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
395 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length 455 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
396 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height 456 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
397 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height 457 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
398 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f; 458 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
399
400
401
402 //System.Console.WriteLine(">>>>>>> [APPEARANCE]: Height {0} Hip offset {1}" + m_avatarHeight + " " + m_hipOffset);
403 //m_log.Debug("------------- Set Appearance Texture ---------------");
404 //Primitive.TextureEntryFace[] faces = Texture.FaceTextures;
405 //foreach (Primitive.TextureEntryFace face in faces)
406 //{
407 // if (face != null)
408 // m_log.Debug(" ++ " + face.TextureID);
409 // else
410 // m_log.Debug(" ++ NULL ");
411 //}
412 //m_log.Debug("----------------------------");
413
414 } 459 }
415 460
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable) 461 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
417 { 462 {
418 m_wearables[wearableId] = wearable; 463// DEBUG ON
464// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
465// DEBUG OFF
466 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
419 } 467 }
420 468
421 public static Primitive.TextureEntry GetDefaultTexture()
422 {
423 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
424 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
425 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
426 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
427 textu.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
428 textu.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
429 textu.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
430 textu.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
431 return textu;
432 }
433
434 public static byte[] GetDefaultVisualParams()
435 {
436 byte[] visualParams;
437 visualParams = new byte[VISUALPARAM_COUNT];
438 for (int i = 0; i < VISUALPARAM_COUNT; i++)
439 {
440 visualParams[i] = 100;
441 }
442 return visualParams;
443 }
444 469
470// DEBUG ON
445 public override String ToString() 471 public override String ToString()
446 { 472 {
447 String s = "[Wearables] =>"; 473 String s = "";
448 s += " Body Item: " + BodyItem.ToString() + ";"; 474 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
449 s += " Skin Item: " + SkinItem.ToString() + ";"; 475 if (m_texture.FaceTextures[i] != null)
450 s += " Shirt Item: " + ShirtItem.ToString() + ";"; 476 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
451 s += " Pants Item: " + PantsItem.ToString() + ";"; 477
452 return s; 478 foreach (AvatarWearable awear in m_wearables)
453 } 479 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
454 480
455 // this is used for OGS1 481 s += "Visual Params: ";
456 public virtual Hashtable ToHashTable() 482 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
457 { 483 s += String.Format("{0},",m_visualparams[j]);
458 Hashtable h = new Hashtable(); 484 s += "\n";
459 h["owner"] = Owner.ToString();
460 h["serial"] = Serial.ToString();
461 h["visual_params"] = VisualParams;
462 h["texture"] = Texture.GetBytes();
463 h["avatar_height"] = AvatarHeight.ToString();
464 h["body_item"] = BodyItem.ToString();
465 h["body_asset"] = BodyAsset.ToString();
466 h["skin_item"] = SkinItem.ToString();
467 h["skin_asset"] = SkinAsset.ToString();
468 h["hair_item"] = HairItem.ToString();
469 h["hair_asset"] = HairAsset.ToString();
470 h["eyes_item"] = EyesItem.ToString();
471 h["eyes_asset"] = EyesAsset.ToString();
472 h["shirt_item"] = ShirtItem.ToString();
473 h["shirt_asset"] = ShirtAsset.ToString();
474 h["pants_item"] = PantsItem.ToString();
475 h["pants_asset"] = PantsAsset.ToString();
476 h["shoes_item"] = ShoesItem.ToString();
477 h["shoes_asset"] = ShoesAsset.ToString();
478 h["socks_item"] = SocksItem.ToString();
479 h["socks_asset"] = SocksAsset.ToString();
480 h["jacket_item"] = JacketItem.ToString();
481 h["jacket_asset"] = JacketAsset.ToString();
482 h["gloves_item"] = GlovesItem.ToString();
483 h["gloves_asset"] = GlovesAsset.ToString();
484 h["undershirt_item"] = UnderShirtItem.ToString();
485 h["undershirt_asset"] = UnderShirtAsset.ToString();
486 h["underpants_item"] = UnderPantsItem.ToString();
487 h["underpants_asset"] = UnderPantsAsset.ToString();
488 h["skirt_item"] = SkirtItem.ToString();
489 h["skirt_asset"] = SkirtAsset.ToString();
490
491 string attachments = GetAttachmentsString();
492 if (attachments != String.Empty)
493 h["attachments"] = attachments;
494
495 return h;
496 }
497
498 public AvatarAppearance(Hashtable h)
499 {
500 Owner = new UUID((string)h["owner"]);
501 Serial = Convert.ToInt32((string)h["serial"]);
502 VisualParams = (byte[])h["visual_params"];
503
504 if (h.Contains("texture"))
505 {
506 byte[] te = h["texture"] as byte[];
507 if (te != null && te.Length > 0)
508 Texture = new Primitive.TextureEntry(te, 0, te.Length);
509 }
510 else
511 {
512 // We shouldn't be receiving appearance hashtables without a TextureEntry,
513 // but in case we do this will prevent a failure when saving to the database
514 Texture = GetDefaultTexture();
515 }
516
517 485
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 486 return s;
519
520 m_wearables = new AvatarWearable[MAX_WEARABLES];
521 for (int i = 0; i < MAX_WEARABLES; i++)
522 {
523 // this makes them all null
524 m_wearables[i] = new AvatarWearable();
525 }
526
527 BodyItem = new UUID((string)h["body_item"]);
528 BodyAsset = new UUID((string)h["body_asset"]);
529 SkinItem = new UUID((string)h["skin_item"]);
530 SkinAsset = new UUID((string)h["skin_asset"]);
531 HairItem = new UUID((string)h["hair_item"]);
532 HairAsset = new UUID((string)h["hair_asset"]);
533 EyesItem = new UUID((string)h["eyes_item"]);
534 EyesAsset = new UUID((string)h["eyes_asset"]);
535 ShirtItem = new UUID((string)h["shirt_item"]);
536 ShirtAsset = new UUID((string)h["shirt_asset"]);
537 PantsItem = new UUID((string)h["pants_item"]);
538 PantsAsset = new UUID((string)h["pants_asset"]);
539 ShoesItem = new UUID((string)h["shoes_item"]);
540 ShoesAsset = new UUID((string)h["shoes_asset"]);
541 SocksItem = new UUID((string)h["socks_item"]);
542 SocksAsset = new UUID((string)h["socks_asset"]);
543 JacketItem = new UUID((string)h["jacket_item"]);
544 JacketAsset = new UUID((string)h["jacket_asset"]);
545 GlovesItem = new UUID((string)h["gloves_item"]);
546 GlovesAsset = new UUID((string)h["gloves_asset"]);
547 UnderShirtItem = new UUID((string)h["undershirt_item"]);
548 UnderShirtAsset = new UUID((string)h["undershirt_asset"]);
549 UnderPantsItem = new UUID((string)h["underpants_item"]);
550 UnderPantsAsset = new UUID((string)h["underpants_asset"]);
551 SkirtItem = new UUID((string)h["skirt_item"]);
552 SkirtAsset = new UUID((string)h["skirt_asset"]);
553
554 if (h.ContainsKey("attachments"))
555 {
556 SetAttachmentsString(h["attachments"].ToString());
557 }
558 } 487 }
488// DEBUG OFF
559 489
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 490 public void SetAttachments(AvatarAttachment[] data)
561
562 public void SetAttachments(AttachmentData[] data)
563 { 491 {
564 foreach (AttachmentData a in data) 492 foreach (AvatarAttachment attach in data)
565 { 493 m_attachments[attach.AttachPoint] = new AvatarAttachment(attach);
566 m_attachments[a.AttachPoint] = new UUID[2];
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 }
570 } 494 }
571 495
572 public void SetAttachments(Hashtable data) 496 public void SetAttachment(int attachpoint, UUID item, UUID asset)
573 { 497 {
574 m_attachments.Clear(); 498 if (attachpoint == 0)
575
576 if (data == null)
577 return; 499 return;
578 500
579 foreach (DictionaryEntry e in data) 501 if (item == UUID.Zero)
580 { 502 {
581 int attachpoint = Convert.ToInt32(e.Key);
582
583 if (m_attachments.ContainsKey(attachpoint)) 503 if (m_attachments.ContainsKey(attachpoint))
584 continue; 504 m_attachments.Remove(attachpoint);
585 505 return;
586 UUID item;
587 UUID asset;
588
589 Hashtable uuids = (Hashtable) e.Value;
590 UUID.TryParse(uuids["item"].ToString(), out item);
591 UUID.TryParse(uuids["asset"].ToString(), out asset);
592
593 UUID[] attachment = new UUID[2];
594 attachment[0] = item;
595 attachment[1] = asset;
596
597 m_attachments[attachpoint] = attachment;
598 } 506 }
599 }
600 507
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 508 m_attachments[attachpoint] = new AvatarAttachment(attachpoint,item,asset);
602 {
603 return m_attachments;
604 } 509 }
605 510
606 public Hashtable GetAttachments() 511 public Hashtable GetAttachments()
@@ -610,16 +515,13 @@ namespace OpenSim.Framework
610 515
611 Hashtable ret = new Hashtable(); 516 Hashtable ret = new Hashtable();
612 517
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 518 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
614 { 519 {
615 int attachpoint = kvp.Key;
616 UUID[] uuids = kvp.Value;
617
618 Hashtable data = new Hashtable(); 520 Hashtable data = new Hashtable();
619 data["item"] = uuids[0].ToString(); 521 data["item"] = kvp.Value.ItemID.ToString();
620 data["asset"] = uuids[1].ToString(); 522 data["asset"] = kvp.Value.AssetID.ToString();
621 523
622 ret[attachpoint] = data; 524 ret[kvp.Key] = data;
623 } 525 }
624 526
625 return ret; 527 return ret;
@@ -635,7 +537,7 @@ namespace OpenSim.Framework
635 if (!m_attachments.ContainsKey(attachpoint)) 537 if (!m_attachments.ContainsKey(attachpoint))
636 return UUID.Zero; 538 return UUID.Zero;
637 539
638 return m_attachments[attachpoint][0]; 540 return m_attachments[attachpoint].ItemID;
639 } 541 }
640 542
641 public UUID GetAttachedAsset(int attachpoint) 543 public UUID GetAttachedAsset(int attachpoint)
@@ -643,33 +545,14 @@ namespace OpenSim.Framework
643 if (!m_attachments.ContainsKey(attachpoint)) 545 if (!m_attachments.ContainsKey(attachpoint))
644 return UUID.Zero; 546 return UUID.Zero;
645 547
646 return m_attachments[attachpoint][1]; 548 return m_attachments[attachpoint].AssetID;
647 }
648
649 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 {
651 if (attachpoint == 0)
652 return;
653
654 if (item == UUID.Zero)
655 {
656 if (m_attachments.ContainsKey(attachpoint))
657 m_attachments.Remove(attachpoint);
658 return;
659 }
660
661 if (!m_attachments.ContainsKey(attachpoint))
662 m_attachments[attachpoint] = new UUID[2];
663
664 m_attachments[attachpoint][0] = item;
665 m_attachments[attachpoint][1] = asset;
666 } 549 }
667 550
668 public int GetAttachpoint(UUID itemID) 551 public int GetAttachpoint(UUID itemID)
669 { 552 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 553 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
671 { 554 {
672 if (kvp.Value[0] == itemID) 555 if (kvp.Value.ItemID == itemID)
673 { 556 {
674 return kvp.Key; 557 return kvp.Key;
675 } 558 }
@@ -690,42 +573,126 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 573 m_attachments.Clear();
691 } 574 }
692 575
693 string GetAttachmentsString() 576 /// <summary>
577 /// Create an OSDMap from the appearance data
578 /// </summary>
579 public OSDMap Pack()
694 { 580 {
695 List<string> strings = new List<string>(); 581 OSDMap data = new OSDMap();
696 582
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 583 data["serial"] = OSD.FromInteger(m_serial);
584 data["height"] = OSD.FromReal(m_avatarHeight);
585 data["hipoffset"] = OSD.FromReal(m_hipOffset);
586
587 // Wearables
588 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
589 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
590 wears.Add(m_wearables[i].Pack());
591 data["wearables"] = wears;
592
593 // Avatar Textures
594 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
595 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 596 {
699 strings.Add(e.Key.ToString()); 597 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 598 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 599 else
600 textures.Add(OSD.FromUUID(UUID.Zero));
702 } 601 }
602 data["textures"] = textures;
703 603
704 return String.Join(",", strings.ToArray()); 604 // Visual Parameters
605 OSDBinary visualparams = new OSDBinary(m_visualparams);
606 data["visualparams"] = visualparams;
607
608 // Attachments
609 OSDArray attachs = new OSDArray(m_attachments.Count);
610 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
611 attachs.Add(kvp.Value.Pack());
612 data["attachments"] = attachs;
613
614 return data;
705 } 615 }
706 616
707 void SetAttachmentsString(string data) 617 /// <summary>
618 /// Unpack and OSDMap and initialize the appearance
619 /// from it
620 /// </summary>
621 public void Unpack(OSDMap data)
708 { 622 {
709 string[] strings = data.Split(new char[] {','}); 623 if ((data != null) && (data["appearance_serial"] != null))
710 int i = 0; 624 m_serial = data["appearance_serial"].AsInteger();
625 if ((data != null) && (data["height"] != null))
626 m_avatarHeight = (float)data["height"].AsReal();
627 if ((data != null) && (data["hipoffset"] != null))
628 m_hipOffset = (float)data["hipoffset"].AsReal();
629
630 try
631 {
632 // Wearables
633 SetDefaultWearables();
634 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
635 {
636 OSDArray wears = (OSDArray)(data["wearables"]);
637 for (int i = 0; i < wears.Count; i++)
638 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
639 }
640 else
641 {
642 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
643 }
711 644
712 m_attachments.Clear(); 645 // Avatar Textures
646 SetDefaultTexture();
647 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
648 {
649 OSDArray textures = (OSDArray)(data["textures"]);
650 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
651 {
652 if (textures[i] != null)
653 {
654 UUID textureID = textures[i].AsUUID();
655 if (textureID != UUID.Zero)
656 m_texture.CreateFace((uint)i).TextureID = textureID;
657 }
658 }
659 }
660 else
661 {
662 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
663 }
713 664
714 while (strings.Length - i > 2) 665 // Visual Parameters
715 { 666 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 667 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 668 {
718 UUID asset = new UUID(strings[i+2]); 669 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 670 m_visualparams = data["visualparams"].AsBinary();
671 }
672 else
673 {
674 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
675 }
720 676
721 if (!m_attachments.ContainsKey(attachpoint)) 677 // Attachments
678 m_attachments = new Dictionary<int, AvatarAttachment>();
679 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 680 {
723 m_attachments[attachpoint] = new UUID[2]; 681 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 682 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 683 {
684 AvatarAttachment attach = new AvatarAttachment((OSDMap)attachs[i]);
685 m_attachments[attach.AttachPoint] = attach;
686 }
726 } 687 }
727 } 688 }
689 catch (Exception e)
690 {
691 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
692 }
728 } 693 }
694
695
729 /// <summary> 696 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 697 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 698 /// Generated from LibOMV's Visual Params list