aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/AvatarAppearance.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/AvatarAppearance.cs')
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs888
1 files changed, 430 insertions, 458 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 5da8ba1..e66a1e7 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, List<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 {
@@ -103,178 +86,135 @@ namespace OpenSim.Framework
103 } 86 }
104 87
105 public virtual UUID BodyItem { 88 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 89 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 90 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 91 }
109 92
110 public virtual UUID BodyAsset { 93 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 94 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 95 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 96 }
114 97
115 public virtual UUID SkinItem { 98 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 99 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 100 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 101 }
119 102
120 public virtual UUID SkinAsset { 103 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 104 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 105 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 106 }
124 107
125 public virtual UUID HairItem { 108 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 109 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 110 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 111 }
129 112
130 public virtual UUID HairAsset { 113 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 114 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 115 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 116 }
134 117
135 public virtual UUID EyesItem { 118 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 119 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 120 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 121 }
139 122
140 public virtual UUID EyesAsset { 123 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 124 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 125 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 126 }
144 127
145 public virtual UUID ShirtItem { 128 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 129 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 130 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 131 }
149 132
150 public virtual UUID ShirtAsset { 133 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 134 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 135 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 136 }
154 137
155 public virtual UUID PantsItem { 138 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 139 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 140 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 141 }
159 142
160 public virtual UUID PantsAsset { 143 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 144 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 145 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 146 }
164 147
165 public virtual UUID ShoesItem { 148 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 149 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 150 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 151 }
169 152
170 public virtual UUID ShoesAsset { 153 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 154 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 155 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 156 }
174 157
175 public virtual UUID SocksItem { 158 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 159 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 160 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 161 }
179 162
180 public virtual UUID SocksAsset { 163 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 164 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 165 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 166 }
184 167
185 public virtual UUID JacketItem { 168 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 169 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 170 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 171 }
189 172
190 public virtual UUID JacketAsset { 173 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 174 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 175 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 176 }
194 177
195 public virtual UUID GlovesItem { 178 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 179 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 180 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 181 }
199 182
200 public virtual UUID GlovesAsset { 183 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 184 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 185 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 186 }
204 187
205 public virtual UUID UnderShirtItem { 188 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 189 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 190 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 191 }
209 192
210 public virtual UUID UnderShirtAsset { 193 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 194 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 195 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 196 }
214 197
215 public virtual UUID UnderPantsItem { 198 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 199 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 200 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 201 }
219 202
220 public virtual UUID UnderPantsAsset { 203 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 204 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 205 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 206 }
224 207
225 public virtual UUID SkirtItem { 208 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 209 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 210 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 211 }
229 212
230 public virtual UUID SkirtAsset { 213 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 214 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 215 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 }
234
235 public virtual void SetDefaultWearables()
236 {
237 m_wearables[BODY].AssetID = BODY_ASSET;
238 m_wearables[BODY].ItemID = BODY_ITEM;
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 }
248
249 public virtual void ClearWearables()
250 {
251 for (int i = 0; i < 13; i++)
252 {
253 m_wearables[i].AssetID = UUID.Zero;
254 m_wearables[i].ItemID = UUID.Zero;
255 }
256 }
257
258 public virtual void SetDefaultParams(byte[] vparams)
259 {
260 // TODO: Figure out better values then 'fat scientist 150' or 'alien 0'
261 for (int i = 0; i < VISUALPARAM_COUNT; i++)
262 {
263 vparams[i] = 150;
264 }
265 }
266
267 protected Primitive.TextureEntry m_texture;
268
269 public virtual Primitive.TextureEntry Texture
270 {
271 get { return m_texture; }
272 set { m_texture = value; }
273 } 216 }
274 217
275 protected float m_avatarHeight = 0;
276 protected float m_hipOffset = 0;
277
278 public virtual float AvatarHeight 218 public virtual float AvatarHeight
279 { 219 {
280 get { return m_avatarHeight; } 220 get { return m_avatarHeight; }
@@ -286,366 +226,301 @@ namespace OpenSim.Framework
286 get { return m_hipOffset; } 226 get { return m_hipOffset; }
287 } 227 }
288 228
289 //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues
290 /*
291 public void BuildVisualParamEnum()
292 {
293 Dictionary<string, int> IndexedParams = new Dictionary<string, int>();
294 int vpIndex = 0;
295 IndexedParams = new Dictionary<string, int>();
296
297 System.Text.StringBuilder sb = new System.Text.StringBuilder();
298
299 sb.Append("public enum VPElement: int\n");
300 sb.Append("{\n");
301 foreach (KeyValuePair<int, VisualParam> kvp in OpenMetaverse.VisualParams.Params)
302 {
303 VisualParam vp = kvp.Value;
304
305 // Only Group-0 parameters are sent in AgentSetAppearance packets
306 if (kvp.Value.Group == 0)
307 {
308
309 if (!IndexedParams.ContainsKey(vp.Name))
310 {
311
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 }
336 if (vpIndex < 217)
337 sb.Append(",\n");
338 else
339 sb.Append("\n");
340
341 }
342 sb.Append("}\n");
343
344 }
345 */
346
347 public AvatarAppearance() : this(UUID.Zero) {} 229 public AvatarAppearance() : this(UUID.Zero) {}
348 230
349 public AvatarAppearance(UUID owner) 231 public AvatarAppearance(UUID owner)
350 { 232 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 233// DEBUG ON
352 for (int i = 0; i < MAX_WEARABLES; i++) 234 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
353 { 235// DEBUG OFF
354 // this makes them all null 236 m_serial = 1;
355 m_wearables[i] = new AvatarWearable();
356 }
357 m_serial = 0;
358 m_owner = owner; 237 m_owner = owner;
359 //BuildVisualParamEnum() 238
360 m_visualparams = new byte[VISUALPARAM_COUNT];
361 // This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
362 SetDefaultParams(m_visualparams);
363 SetDefaultWearables(); 239 SetDefaultWearables();
364 m_texture = GetDefaultTexture(); 240 SetDefaultTexture();
241 SetDefaultParams();
242 SetHeight();
243
244 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
365 } 245 }
366 246
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 247 public AvatarAppearance(UUID avatarID, OSDMap map)
368 { 248 {
249// DEBUG ON
250 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
251// DEBUG OFF
369 m_owner = avatarID; 252 m_owner = avatarID;
370 m_serial = 1; 253 Unpack(map);
371 m_wearables = wearables; 254 SetHeight();
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 255 }
375 256
376 /// <summary> 257 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
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 { 258 {
259// DEBUG ON
260 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
261// DEBUG OFF
262 m_serial = 1;
263 m_owner = avatarID;
264
265 if (wearables != null)
266 m_wearables = wearables;
267 else
268 SetDefaultWearables();
269
381 if (textureEntry != null) 270 if (textureEntry != null)
382 m_texture = textureEntry; 271 m_texture = textureEntry;
272 else
273 SetDefaultTexture();
274
383 if (visualParams != null) 275 if (visualParams != null)
384 m_visualparams = visualParams; 276 m_visualparams = visualParams;
277 else
278 SetDefaultParams();
385 279
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 280 SetHeight();
387 + 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
389 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
390 + 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
392 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
393 m_hipOffset = (((1.23077f // Half of avatar
394 + 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
396 + 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
398 ) / 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 }
415
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
417 {
418 m_wearables[wearableId] = wearable;
419 }
420 281
421 public static Primitive.TextureEntry GetDefaultTexture() 282 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
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 } 283 }
433 284
434 public static byte[] GetDefaultVisualParams() 285 public AvatarAppearance(AvatarAppearance appearance)
435 { 286 {
436 byte[] visualParams; 287// DEBUG ON
437 visualParams = new byte[VISUALPARAM_COUNT]; 288 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
438 for (int i = 0; i < VISUALPARAM_COUNT; i++) 289// DEBUG OFF
290 if (appearance == null)
439 { 291 {
440 visualParams[i] = 100; 292 m_serial = 1;
441 } 293 m_owner = UUID.Zero;
442 return visualParams;
443 }
444 294
445 public override String ToString() 295 SetDefaultWearables();
446 { 296 SetDefaultTexture();
447 String s = "[Wearables] =>"; 297 SetDefaultParams();
448 s += " Body Item: " + BodyItem.ToString() + ";"; 298 SetHeight();
449 s += " Skin Item: " + SkinItem.ToString() + ";";
450 s += " Shirt Item: " + ShirtItem.ToString() + ";";
451 s += " Pants Item: " + PantsItem.ToString() + ";";
452 return s;
453 }
454 299
455 // this is used for OGS1 300 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
456 public virtual Hashtable ToHashTable()
457 {
458 Hashtable h = new Hashtable();
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 301
504 if (h.Contains("texture")) 302 return;
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 } 303 }
516
517 304
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 305 m_serial = appearance.Serial;
306 m_owner = appearance.Owner;
519 307
520 m_wearables = new AvatarWearable[MAX_WEARABLES]; 308 m_wearables = null;
521 for (int i = 0; i < MAX_WEARABLES; i++) 309 if (appearance.Wearables != null)
522 { 310 {
523 // this makes them all null 311 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
524 m_wearables[i] = new AvatarWearable(); 312 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
313 SetWearable(i,appearance.Wearables[i]);
525 } 314 }
526 315
527 BodyItem = new UUID((string)h["body_item"]); 316 m_texture = null;
528 BodyAsset = new UUID((string)h["body_asset"]); 317 if (appearance.Texture != null)
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 { 318 {
556 SetAttachmentsString(h["attachments"].ToString()); 319 byte[] tbytes = appearance.Texture.GetBytes();
320 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
557 } 321 }
322
323 m_visualparams = null;
324 if (appearance.VisualParams != null)
325 m_visualparams = (byte[])appearance.VisualParams.Clone();
326
327 // Copy the attachment, force append mode since that ensures consistency
328 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
329 foreach (AvatarAttachment attachment in appearance.GetAttachments())
330 AppendAttachment(new AvatarAttachment(attachment));
331 }
332
333 protected virtual void SetDefaultWearables()
334 {
335 m_wearables = AvatarWearable.DefaultWearables;
558 } 336 }
559 337
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 338 protected virtual void SetDefaultParams()
561
562 public void SetAttachments(AttachmentData[] data)
563 { 339 {
564 foreach (AttachmentData a in data) 340 m_visualparams = new byte[VISUALPARAM_COUNT];
341 for (int i = 0; i < VISUALPARAM_COUNT; i++)
565 { 342 {
566 m_attachments[a.AttachPoint] = new UUID[2]; 343 m_visualparams[i] = 150;
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 } 344 }
570 } 345 }
571 346
572 public void SetAttachments(Hashtable data) 347 protected virtual void SetDefaultTexture()
573 { 348 {
574 m_attachments.Clear(); 349 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
575 350 // The initialization of these seems to force a rebake regardless of whether it is needed
576 if (data == null) 351 // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
577 return; 352 // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
353 // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
354 // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
355 // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
356 // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
357 // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
358 }
578 359
579 foreach (DictionaryEntry e in data) 360 /// <summary>
361 /// Set up appearance textures.
362 /// Returns boolean that indicates whether the new entries actually change the
363 /// existing values.
364 /// </summary>
365 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
366 {
367 if (textureEntry == null)
368 return false;
369
370 // There are much simpler versions of this copy that could be
371 // made. We determine if any of the textures actually
372 // changed to know if the appearance should be saved later
373 bool changed = false;
374 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
580 { 375 {
581 int attachpoint = Convert.ToInt32(e.Key); 376 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
582 377 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
583 if (m_attachments.ContainsKey(attachpoint)) 378
584 continue; 379 if (newface == null)
380 {
381 if (oldface == null) continue;
382 }
383 else
384 {
385 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
386 }
585 387
586 UUID item; 388 m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
587 UUID asset; 389 changed = true;
390// DEBUG ON
391 if (newface != null)
392 m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID);
393// DEBUG OFF
394 }
588 395
589 Hashtable uuids = (Hashtable) e.Value; 396 return changed;
590 UUID.TryParse(uuids["item"].ToString(), out item); 397 }
591 UUID.TryParse(uuids["asset"].ToString(), out asset); 398
399 /// <summary>
400 /// Set up visual parameters for the avatar and refresh the avatar height
401 /// Returns boolean that indicates whether the new entries actually change the
402 /// existing values.
403 /// </summary>
404 public virtual bool SetVisualParams(byte[] visualParams)
405 {
406 if (visualParams == null)
407 return false;
408
409 // There are much simpler versions of this copy that could be
410 // made. We determine if any of the visual parameters actually
411 // changed to know if the appearance should be saved later
412 bool changed = false;
413 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
414 {
415 if (visualParams[i] != m_visualparams[i])
416 {
417// DEBUG ON
418 m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
419 i,m_visualparams[i],visualParams[i]);
420// DEBUG OFF
421 m_visualparams[i] = visualParams[i];
422 changed = true;
423 }
424 }
592 425
593 UUID[] attachment = new UUID[2]; 426 // Reset the height if the visual parameters actually changed
594 attachment[0] = item; 427 if (changed)
595 attachment[1] = asset; 428 SetHeight();
596 429
597 m_attachments[attachpoint] = attachment; 430 return changed;
598 }
599 } 431 }
600 432
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 433 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
602 { 434 {
603 return m_attachments; 435 SetTextureEntries(textureEntry);
436 SetVisualParams(visualParams);
604 } 437 }
438
439 public virtual void SetHeight()
440 {
441 m_avatarHeight = 1.23077f // Shortest possible avatar height
442 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
443 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
444 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
445 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
446 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
447 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
605 448
606 public Hashtable GetAttachments() 449 m_hipOffset = (((1.23077f // Half of avatar
450 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
451 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
452 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
453 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
454 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
455 }
456
457 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
607 { 458 {
608 if (m_attachments.Count == 0) 459// DEBUG ON
609 return null; 460// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
461// DEBUG OFF
462 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
463 }
610 464
611 Hashtable ret = new Hashtable();
612 465
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 466// DEBUG ON
614 { 467 public override String ToString()
615 int attachpoint = kvp.Key; 468 {
616 UUID[] uuids = kvp.Value; 469 String s = "";
617 470
618 Hashtable data = new Hashtable(); 471 s += String.Format("Serial: {0}\n",m_serial);
619 data["item"] = uuids[0].ToString(); 472
620 data["asset"] = uuids[1].ToString(); 473 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
474 if (m_texture.FaceTextures[i] != null)
475 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
621 476
622 ret[attachpoint] = data; 477 foreach (AvatarWearable awear in m_wearables)
623 } 478 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
624 479
625 return ret; 480 s += "Visual Params: ";
481 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
482 s += String.Format("{0},",m_visualparams[j]);
483 s += "\n";
484
485 return s;
626 } 486 }
487// DEBUG OFF
627 488
628 public List<int> GetAttachedPoints() 489 /// <summary>
490 /// Get a list of the attachments, note that there may be
491 /// duplicate attachpoints
492 /// </summary>
493 public List<AvatarAttachment> GetAttachments()
629 { 494 {
630 return new List<int>(m_attachments.Keys); 495 List<AvatarAttachment> alist = new List<AvatarAttachment>();
496 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
497 {
498 foreach (AvatarAttachment attach in kvp.Value)
499 alist.Add(new AvatarAttachment(attach));
500 }
501
502 return alist;
631 } 503 }
632 504
633 public UUID GetAttachedItem(int attachpoint) 505 internal void AppendAttachment(AvatarAttachment attach)
634 { 506 {
635 if (!m_attachments.ContainsKey(attachpoint)) 507 if (! m_attachments.ContainsKey(attach.AttachPoint))
636 return UUID.Zero; 508 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
637 509 m_attachments[attach.AttachPoint].Add(attach);
638 return m_attachments[attachpoint][0];
639 } 510 }
640 511
641 public UUID GetAttachedAsset(int attachpoint) 512 internal void ReplaceAttachment(AvatarAttachment attach)
642 { 513 {
643 if (!m_attachments.ContainsKey(attachpoint)) 514 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
644 return UUID.Zero; 515 m_attachments[attach.AttachPoint].Add(attach);
645
646 return m_attachments[attachpoint][1];
647 } 516 }
648 517
518 /// <summary>
519 /// Add an attachment, if the attachpoint has the
520 /// 0x80 bit set then we assume this is an append
521 /// operation otherwise we replace whatever is
522 /// currently attached at the attachpoint
523 /// </summary>
649 public void SetAttachment(int attachpoint, UUID item, UUID asset) 524 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 { 525 {
651 if (attachpoint == 0) 526 if (attachpoint == 0)
@@ -658,31 +533,47 @@ namespace OpenSim.Framework
658 return; 533 return;
659 } 534 }
660 535
661 if (!m_attachments.ContainsKey(attachpoint)) 536 // check if this is an append or a replace, 0x80 marks it as an append
662 m_attachments[attachpoint] = new UUID[2]; 537 if ((attachpoint & 0x80) > 0)
663 538 {
664 m_attachments[attachpoint][0] = item; 539 // strip the append bit
665 m_attachments[attachpoint][1] = asset; 540 int point = attachpoint & 0x7F;
541 AppendAttachment(new AvatarAttachment(point, item, asset));
542 }
543 else
544 {
545 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
546 }
666 } 547 }
667 548
668 public int GetAttachpoint(UUID itemID) 549 public int GetAttachpoint(UUID itemID)
669 { 550 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 551 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
671 { 552 {
672 if (kvp.Value[0] == itemID) 553 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
673 { 554 if (index >= 0)
674 return kvp.Key; 555 return kvp.Key;
675 }
676 } 556 }
557
677 return 0; 558 return 0;
678 } 559 }
679 560
680 public void DetachAttachment(UUID itemID) 561 public void DetachAttachment(UUID itemID)
681 { 562 {
682 int attachpoint = GetAttachpoint(itemID); 563 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
564 {
565 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
566 if (index >= 0)
567 {
568 // Remove it from the list of attachments at that attach point
569 m_attachments[kvp.Key].RemoveAt(index);
683 570
684 if (attachpoint > 0) 571 // And remove the list if there are no more attachments here
685 m_attachments.Remove(attachpoint); 572 if (m_attachments[kvp.Key].Count == 0)
573 m_attachments.Remove(kvp.Key);
574 return;
575 }
576 }
686 } 577 }
687 578
688 public void ClearAttachments() 579 public void ClearAttachments()
@@ -690,42 +581,123 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 581 m_attachments.Clear();
691 } 582 }
692 583
693 string GetAttachmentsString() 584 /// <summary>
585 /// Create an OSDMap from the appearance data
586 /// </summary>
587 public OSDMap Pack()
694 { 588 {
695 List<string> strings = new List<string>(); 589 OSDMap data = new OSDMap();
696 590
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 591 data["serial"] = OSD.FromInteger(m_serial);
592 data["height"] = OSD.FromReal(m_avatarHeight);
593 data["hipoffset"] = OSD.FromReal(m_hipOffset);
594
595 // Wearables
596 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
597 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
598 wears.Add(m_wearables[i].Pack());
599 data["wearables"] = wears;
600
601 // Avatar Textures
602 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
603 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 604 {
699 strings.Add(e.Key.ToString()); 605 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 606 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 607 else
608 textures.Add(OSD.FromUUID(UUID.Zero));
702 } 609 }
610 data["textures"] = textures;
703 611
704 return String.Join(",", strings.ToArray()); 612 // Visual Parameters
613 OSDBinary visualparams = new OSDBinary(m_visualparams);
614 data["visualparams"] = visualparams;
615
616 // Attachments
617 OSDArray attachs = new OSDArray(m_attachments.Count);
618 foreach (AvatarAttachment attach in GetAttachments())
619 attachs.Add(attach.Pack());
620 data["attachments"] = attachs;
621
622 return data;
705 } 623 }
706 624
707 void SetAttachmentsString(string data) 625 /// <summary>
626 /// Unpack and OSDMap and initialize the appearance
627 /// from it
628 /// </summary>
629 public void Unpack(OSDMap data)
708 { 630 {
709 string[] strings = data.Split(new char[] {','}); 631 if ((data != null) && (data["serial"] != null))
710 int i = 0; 632 m_serial = data["serial"].AsInteger();
633 if ((data != null) && (data["height"] != null))
634 m_avatarHeight = (float)data["height"].AsReal();
635 if ((data != null) && (data["hipoffset"] != null))
636 m_hipOffset = (float)data["hipoffset"].AsReal();
637
638 try
639 {
640 // Wearables
641 SetDefaultWearables();
642 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
643 {
644 OSDArray wears = (OSDArray)(data["wearables"]);
645 for (int i = 0; i < wears.Count; i++)
646 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
647 }
648 else
649 {
650 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
651 }
711 652
712 m_attachments.Clear(); 653 // Avatar Textures
654 SetDefaultTexture();
655 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
656 {
657 OSDArray textures = (OSDArray)(data["textures"]);
658 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
659 {
660 if (textures[i] != null)
661 {
662 UUID textureID = textures[i].AsUUID();
663 if (textureID != UUID.Zero)
664 m_texture.CreateFace((uint)i).TextureID = textureID;
665 }
666 }
667 }
668 else
669 {
670 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
671 }
713 672
714 while (strings.Length - i > 2) 673 // Visual Parameters
715 { 674 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 675 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 676 {
718 UUID asset = new UUID(strings[i+2]); 677 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 678 m_visualparams = data["visualparams"].AsBinary();
679 }
680 else
681 {
682 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
683 }
720 684
721 if (!m_attachments.ContainsKey(attachpoint)) 685 // Attachments
686 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
687 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 688 {
723 m_attachments[attachpoint] = new UUID[2]; 689 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 690 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 691 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
726 } 692 }
727 } 693 }
694 catch (Exception e)
695 {
696 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
697 }
728 } 698 }
699
700
729 /// <summary> 701 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 702 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 703 /// Generated from LibOMV's Visual Params list