clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Reflection;
30 using System.Collections;
31 using System.Collections.Generic;
32 using OpenMetaverse;
33 using OpenMetaverse.StructuredData;
34 using log4net;
35  
36 namespace OpenSim.Framework
37 {
38 /// <summary>
39 /// Contains the Avatar's Appearance and methods to manipulate the appearance.
40 /// </summary>
41 public class AvatarAppearance
42 {
43 // SL box diferent to size
44 const float AVBOXAJUST = 0.2f;
45 // constrains for ubitode physics
46 const float AVBOXMINX = 0.2f;
47 const float AVBOXMINY = 0.3f;
48 const float AVBOXMINZ = 1.2f;
49  
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51  
52 // this is viewer capabilities and weared things dependent
53 // should be only used as initial default value ( V1 viewers )
54 public readonly static int VISUALPARAM_COUNT = 218;
55  
56 public readonly static int TEXTURE_COUNT = 21;
57 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
58  
59 protected int m_serial = 0;
60 protected byte[] m_visualparams;
61 protected Primitive.TextureEntry m_texture;
62 protected AvatarWearable[] m_wearables;
63 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
64 protected float m_avatarHeight = 0;
65 protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value
66 protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
67 protected float m_avatarFeetOffset = 0;
68 protected float m_avatarAnimOffset = 0;
69 protected WearableCacheItem[] m_cacheitems;
70 protected bool m_cacheItemsDirty = true;
71  
72 public virtual int Serial
73 {
74 get { return m_serial; }
75 set { m_serial = value; }
76 }
77  
78 public virtual byte[] VisualParams
79 {
80 get { return m_visualparams; }
81 set { m_visualparams = value; }
82 }
83  
84 public virtual Vector3 AvatarSize
85 {
86 get { return m_avatarSize; }
87 }
88  
89 public virtual Vector3 AvatarBoxSize
90 {
91 get { return m_avatarBoxSize; }
92 }
93  
94 public virtual float AvatarFeetOffset
95 {
96 get { return m_avatarFeetOffset + m_avatarAnimOffset; }
97 }
98  
99 public virtual Primitive.TextureEntry Texture
100 {
101 get { return m_texture; }
102 set
103 {
104 // m_log.DebugFormat("[AVATAR APPEARANCE]: Set TextureEntry to {0}", value);
105 m_texture = value;
106 }
107 }
108  
109 public virtual AvatarWearable[] Wearables
110 {
111 get { return m_wearables; }
112 set { m_wearables = value; }
113 }
114  
115 public virtual float AvatarHeight
116 {
117 get { return m_avatarHeight; }
118 set { m_avatarHeight = value; }
119 }
120  
121 public virtual WearableCacheItem[] WearableCacheItems
122 {
123 get { return m_cacheitems; }
124 set { m_cacheitems = value; }
125 }
126  
127 public virtual bool WearableCacheItemsDirty
128 {
129 get { return m_cacheItemsDirty; }
130 set { m_cacheItemsDirty = value; }
131 }
132  
133 public AvatarAppearance()
134 {
135 // m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
136  
137 m_serial = 0;
138 SetDefaultWearables();
139 SetDefaultTexture();
140 SetDefaultParams();
141 // SetHeight();
142 SetSize(new Vector3(0.45f,0.6f,1.9f));
143 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
144 }
145  
146 public AvatarAppearance(OSDMap map)
147 {
148 // m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap");
149  
150 Unpack(map);
151 // SetHeight(); done in Unpack
152 }
153  
154 public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
155 {
156 // m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
157  
158 m_serial = 0;
159  
160 if (wearables != null)
161 m_wearables = wearables;
162 else
163 SetDefaultWearables();
164  
165 if (textureEntry != null)
166 m_texture = textureEntry;
167 else
168 SetDefaultTexture();
169  
170 if (visualParams != null)
171 m_visualparams = visualParams;
172 else
173 SetDefaultParams();
174  
175 // SetHeight();
176 if(m_avatarHeight == 0)
177 SetSize(new Vector3(0.45f,0.6f,1.9f));
178  
179 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
180 }
181  
182 public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
183 {
184 }
185  
186 public AvatarAppearance(AvatarAppearance appearance, bool copyWearables)
187 {
188 // m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
189  
190 if (appearance == null)
191 {
192 m_serial = 0;
193 SetDefaultWearables();
194 SetDefaultTexture();
195 SetDefaultParams();
196 // SetHeight();
197 SetSize(new Vector3(0.45f, 0.6f, 1.9f));
198 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
199  
200 return;
201 }
202  
203 m_serial = appearance.Serial;
204  
205 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
206 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
207 m_wearables[i] = new AvatarWearable();
208  
209 if (copyWearables && (appearance.Wearables != null))
210 {
211 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
212 SetWearable(i,appearance.Wearables[i]);
213 }
214  
215 m_texture = null;
216 if (appearance.Texture != null)
217 {
218 byte[] tbytes = appearance.Texture.GetBytes();
219 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
220 }
221  
222 m_visualparams = null;
223 if (appearance.VisualParams != null)
224 m_visualparams = (byte[])appearance.VisualParams.Clone();
225  
226 // m_avatarHeight = appearance.m_avatarHeight;
227 SetSize(appearance.AvatarSize);
228  
229 // Copy the attachment, force append mode since that ensures consistency
230 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
231 foreach (AvatarAttachment attachment in appearance.GetAttachments())
232 AppendAttachment(new AvatarAttachment(attachment));
233 }
234  
235 public void GetAssetsFrom(AvatarAppearance app)
236 {
237 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
238 {
239 for (int j = 0; j < m_wearables[i].Count; j++)
240 {
241 UUID itemID = m_wearables[i][j].ItemID;
242 UUID assetID = app.Wearables[i].GetAsset(itemID);
243  
244 if (assetID != UUID.Zero)
245 m_wearables[i].Add(itemID, assetID);
246 }
247 }
248 }
249  
250 public void ClearWearables()
251 {
252 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
253 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
254 m_wearables[i] = new AvatarWearable();
255 }
256  
257 protected virtual void SetDefaultWearables()
258 {
259 m_wearables = AvatarWearable.DefaultWearables;
260 }
261  
262 /// <summary>
263 /// Invalidate all of the baked textures in the appearance, useful
264 /// if you know that none are valid
265 /// </summary>
266 public virtual void ResetAppearance()
267 {
268 // m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance");
269  
270 m_serial = 0;
271  
272 SetDefaultTexture();
273  
274 //for (int i = 0; i < BAKE_INDICES.Length; i++)
275 // {
276 // int idx = BAKE_INDICES[i];
277 // m_texture.FaceTextures[idx].TextureID = UUID.Zero;
278 // }
279 }
280  
281 protected virtual void SetDefaultParams()
282 {
283 m_visualparams = new byte[] { 33,61,85,23,58,127,63,85,63,42,0,85,63,36,85,95,153,63,34,0,63,109,88,132,63,136,81,85,103,136,127,0,150,150,150,127,0,0,0,0,0,127,0,0,255,127,114,127,99,63,127,140,127,127,0,0,0,191,0,104,0,0,0,0,0,0,0,0,0,145,216,133,0,127,0,127,170,0,0,127,127,109,85,127,127,63,85,42,150,150,150,150,150,150,150,25,150,150,150,0,127,0,0,144,85,127,132,127,85,0,127,127,127,127,127,127,59,127,85,127,127,106,47,79,127,127,204,2,141,66,0,0,127,127,0,0,0,0,127,0,159,0,0,178,127,36,85,131,127,127,127,153,95,0,140,75,27,127,127,0,150,150,198,0,0,63,30,127,165,209,198,127,127,153,204,51,51,255,255,255,204,0,255,150,150,150,150,150,150,150,150,150,150,0,150,150,150,150,150,0,127,127,150,150,150,150,150,150,150,150,0,0,150,51,132,150,150,150 };
284 // for (int i = 0; i < VISUALPARAM_COUNT; i++)
285 // {
286 // m_visualparams[i] = 150;
287 // }
288 }
289  
290 /// <summary>
291 /// Invalidate all of the baked textures in the appearance, useful
292 /// if you know that none are valid
293 /// </summary>
294 public virtual void ResetBakedTextures()
295 {
296 SetDefaultTexture();
297  
298 //for (int i = 0; i < BAKE_INDICES.Length; i++)
299 // {
300 // int idx = BAKE_INDICES[i];
301 // m_texture.FaceTextures[idx].TextureID = UUID.Zero;
302 // }
303 }
304  
305 protected virtual void SetDefaultTexture()
306 {
307 m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
308  
309 // for (uint i = 0; i < TEXTURE_COUNT; i++)
310 // m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
311 }
312  
313 /// <summary>
314 /// Set up appearance texture ids.
315 /// </summary>
316 /// <returns>
317 /// True if any existing texture id was changed by the new data.
318 /// False if there were no changes or no existing texture ids.
319 /// </returns>
320 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
321 {
322 if (textureEntry == null)
323 return false;
324  
325 // There are much simpler versions of this copy that could be
326 // made. We determine if any of the textures actually
327 // changed to know if the appearance should be saved later
328 bool changed = false;
329 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
330 {
331 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
332 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
333  
334 if (newface == null)
335 {
336 if (oldface == null)
337 continue;
338 }
339 else
340 {
341 if (oldface != null && oldface.TextureID == newface.TextureID)
342 continue;
343 }
344  
345 changed = true;
346 }
347  
348 m_texture = textureEntry;
349  
350 return changed;
351 }
352  
353 /// <summary>
354 /// Set up visual parameters for the avatar and refresh the avatar height
355 /// </summary>
356 /// <returns>
357 /// True if any existing visual parameter was changed by the new data.
358 /// False if there were no changes or no existing visual parameters.
359 /// </returns>
360 public virtual bool SetVisualParams(byte[] visualParams)
361 {
362 if (visualParams == null)
363 return false;
364  
365 // There are much simpler versions of this copy that could be
366 // made. We determine if any of the visual parameters actually
367 // changed to know if the appearance should be saved later
368 bool changed = false;
369  
370 int newsize = visualParams.Length;
371  
372 if (newsize != m_visualparams.Length)
373 {
374 changed = true;
375 m_visualparams = (byte[])visualParams.Clone();
376 }
377 else
378 {
379  
380 for (int i = 0; i < newsize; i++)
381 {
382 if (visualParams[i] != m_visualparams[i])
383 {
384 // DEBUG ON
385 // m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
386 // i,m_visualparams[i],visualParams[i]);
387 // DEBUG OFF
388 m_visualparams[i] = visualParams[i];
389 changed = true;
390 }
391 }
392 }
393 // Reset the height if the visual parameters actually changed
394 // if (changed)
395 // SetHeight();
396  
397 return changed;
398 }
399  
400 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
401 {
402 SetTextureEntries(textureEntry);
403 SetVisualParams(visualParams);
404 }
405  
406 /// <summary>
407 /// Set avatar height by a calculation based on their visual parameters.
408 /// </summary>
409 public virtual void SetHeight()
410 {
411 /*
412 // Start with shortest possible female avatar height
413 m_avatarHeight = 1.14597f;
414 // Add offset for male avatars
415 if (m_visualparams[(int)VPElement.SHAPE_MALE] != 0)
416 m_avatarHeight += 0.0848f;
417 // Add offsets for visual params
418 m_avatarHeight += 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f
419 + 0.08117f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f
420 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f
421 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f
422 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f
423 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f;
424 */
425 }
426  
427 public void SetSize(Vector3 avSize)
428 {
429 if (avSize.X > 32f)
430 avSize.X = 32f;
431 else if (avSize.X < 0.1f)
432 avSize.X = 0.1f;
433  
434 if (avSize.Y > 32f)
435 avSize.Y = 32f;
436 else if (avSize.Y < 0.1f)
437 avSize.Y = 0.1f;
438 if (avSize.Z > 32f)
439 avSize.Z = 32f;
440 else if (avSize.Z < 0.1f)
441 avSize.Z = 0.1f;
442  
443 m_avatarSize = avSize;
444 m_avatarBoxSize = avSize;
445 m_avatarBoxSize.Z += AVBOXAJUST;
446 if (m_avatarBoxSize.X < AVBOXMINX)
447 m_avatarBoxSize.X = AVBOXMINX;
448 if (m_avatarBoxSize.Y < AVBOXMINY)
449 m_avatarBoxSize.Y = AVBOXMINY;
450 if (m_avatarBoxSize.Z < AVBOXMINZ)
451 m_avatarBoxSize.Z = AVBOXMINZ;
452 m_avatarHeight = m_avatarSize.Z;
453 }
454  
455 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
456 {
457 // DEBUG ON
458 // m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
459 // DEBUG OFF
460 m_wearables[wearableId].Clear();
461 for (int i = 0; i < wearable.Count; i++)
462 m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID);
463 }
464  
465 // DEBUG ON
466 public override String ToString()
467 {
468 String s = "";
469  
470 s += String.Format("Serial: {0}\n",m_serial);
471  
472 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
473 if (m_texture.FaceTextures[i] != null)
474 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
475  
476 foreach (AvatarWearable awear in m_wearables)
477 {
478 for (int i = 0; i < awear.Count; i++)
479 s += String.Format("Wearable: item={0}, asset={1}\n",awear[i].ItemID,awear[i].AssetID);
480 }
481  
482 s += "Visual Params: ";
483 // for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
484 for (uint j = 0; j < m_visualparams.Length; j++)
485 s += String.Format("{0},",m_visualparams[j]);
486 s += "\n";
487  
488 return s;
489 }
490 // DEBUG OFF
491  
492 /// <summary>
493 /// Get a list of the attachments.
494 /// </summary>
495 /// <remarks>
496 /// There may be duplicate attachpoints
497 /// </remarks>
498 public List<AvatarAttachment> GetAttachments()
499 {
500 lock (m_attachments)
501 {
502 List<AvatarAttachment> alist = new List<AvatarAttachment>();
503 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
504 {
505 foreach (AvatarAttachment attach in kvp.Value)
506 alist.Add(new AvatarAttachment(attach));
507 }
508 return alist;
509 }
510 }
511  
512 internal void AppendAttachment(AvatarAttachment attach)
513 {
514 // m_log.DebugFormat(
515 // "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
516 // attach.ItemID, attach.AssetID, attach.AttachPoint);
517  
518 lock (m_attachments)
519 {
520 if (!m_attachments.ContainsKey(attach.AttachPoint))
521 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
522  
523 foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint])
524 {
525 if (prev.ItemID == attach.ItemID)
526 return;
527 }
528  
529 m_attachments[attach.AttachPoint].Add(attach);
530 }
531 }
532  
533 internal void ReplaceAttachment(AvatarAttachment attach)
534 {
535 // m_log.DebugFormat(
536 // "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
537 // attach.ItemID, attach.AssetID, attach.AttachPoint);
538  
539 lock (m_attachments)
540 {
541 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
542 m_attachments[attach.AttachPoint].Add(attach);
543 }
544 }
545  
546 /// <summary>
547 /// Set an attachment
548 /// </summary>
549 /// <remarks>
550 /// If the attachpoint has the
551 /// 0x80 bit set then we assume this is an append
552 /// operation otherwise we replace whatever is
553 /// currently attached at the attachpoint
554 /// </remarks>
555 /// <param name="attachpoint"></param>
556 /// <param name="item">If UUID.Zero, then an any attachment at the attachpoint is removed.</param>
557 /// <param name="asset"></param>
558 /// <returns>
559 /// return true if something actually changed
560 /// </returns>
561 public bool SetAttachment(int attachpoint, UUID item, UUID asset)
562 {
563 // m_log.DebugFormat(
564 // "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
565 // attachpoint, item, asset);
566  
567 if (attachpoint == 0)
568 return false;
569  
570 lock (m_attachments)
571 {
572 if (item == UUID.Zero)
573 {
574 if (m_attachments.ContainsKey(attachpoint))
575 {
576 m_attachments.Remove(attachpoint);
577 return true;
578 }
579  
580 return false;
581 }
582  
583 // When a user logs in, the attachment item ids are pulled from persistence in the Avatars table. However,
584 // the asset ids are not saved. When the avatar enters a simulator the attachments are set again. If
585 // we simply perform an item check here then the asset ids (which are now present) are never set, and NPC attachments
586 // later fail unless the attachment is detached and reattached.
587 //
588 // Therefore, we will carry on with the set if the existing attachment has no asset id.
589 AvatarAttachment existingAttachment = GetAttachmentForItem(item);
590 if (existingAttachment != null)
591 {
592 // m_log.DebugFormat(
593 // "[AVATAR APPEARANCE]: Found existing attachment for {0}, asset {1} at point {2}",
594 // existingAttachment.ItemID, existingAttachment.AssetID, existingAttachment.AttachPoint);
595  
596 if (existingAttachment.AssetID != UUID.Zero && existingAttachment.AttachPoint == (attachpoint & 0x7F))
597 {
598 m_log.DebugFormat(
599 "[AVATAR APPEARANCE]: Ignoring attempt to attach an already attached item {0} at point {1}",
600 item, attachpoint);
601  
602 return false;
603 }
604 else
605 {
606 // Remove it here so that the later append does not add a second attachment but we still update
607 // the assetID
608 DetachAttachment(existingAttachment.ItemID);
609 }
610 }
611  
612 // check if this is an append or a replace, 0x80 marks it as an append
613 if ((attachpoint & 0x80) > 0)
614 {
615 // strip the append bit
616 int point = attachpoint & 0x7F;
617 AppendAttachment(new AvatarAttachment(point, item, asset));
618 }
619 else
620 {
621 ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
622 }
623 }
624  
625 return true;
626 }
627  
628 /// <summary>
629 /// If the item is already attached, return it.
630 /// </summary>
631 /// <param name="itemID"></param>
632 /// <returns>Returns null if this item is not attached.</returns>
633 public AvatarAttachment GetAttachmentForItem(UUID itemID)
634 {
635 lock (m_attachments)
636 {
637 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
638 {
639 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
640 if (index >= 0)
641 return kvp.Value[index];
642 }
643 }
644  
645 return null;
646 }
647  
648 public int GetAttachpoint(UUID itemID)
649 {
650 lock (m_attachments)
651 {
652 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
653 {
654 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
655 if (index >= 0)
656 return kvp.Key;
657 }
658 }
659 return 0;
660 }
661  
662 public bool DetachAttachment(UUID itemID)
663 {
664 lock (m_attachments)
665 {
666 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
667 {
668 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
669 if (index >= 0)
670 {
671 // m_log.DebugFormat(
672 // "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}",
673 // m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint);
674  
675 // Remove it from the list of attachments at that attach point
676 m_attachments[kvp.Key].RemoveAt(index);
677  
678 // And remove the list if there are no more attachments here
679 if (m_attachments[kvp.Key].Count == 0)
680 m_attachments.Remove(kvp.Key);
681  
682 return true;
683 }
684 }
685 }
686  
687 return false;
688 }
689  
690 public void ClearAttachments()
691 {
692 lock (m_attachments)
693 m_attachments.Clear();
694 }
695  
696 #region Packing Functions
697  
698 /// <summary>
699 /// Create an OSDMap from the appearance data
700 /// </summary>
701 public OSDMap Pack()
702 {
703 OSDMap data = new OSDMap();
704  
705 data["serial"] = OSD.FromInteger(m_serial);
706 data["height"] = OSD.FromReal(m_avatarHeight);
707  
708 // Wearables
709 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
710 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
711 wears.Add(m_wearables[i].Pack());
712 data["wearables"] = wears;
713  
714 // Avatar Textures
715 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
716 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
717 {
718 if (m_texture.FaceTextures[i] != null)
719 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
720 else
721 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
722 }
723 data["textures"] = textures;
724  
725 // Visual Parameters
726 OSDBinary visualparams = new OSDBinary(m_visualparams);
727 data["visualparams"] = visualparams;
728  
729 lock (m_attachments)
730 {
731 // Attachments
732 OSDArray attachs = new OSDArray(m_attachments.Count);
733 foreach (AvatarAttachment attach in GetAttachments())
734 attachs.Add(attach.Pack());
735 data["attachments"] = attachs;
736 }
737  
738 return data;
739 }
740  
741 /// <summary>
742 /// Unpack and OSDMap and initialize the appearance
743 /// from it
744 /// </summary>
745 public void Unpack(OSDMap data)
746 {
747 if ((data != null) && (data["serial"] != null))
748 m_serial = data["serial"].AsInteger();
749 if ((data != null) && (data["height"] != null))
750 // m_avatarHeight = (float)data["height"].AsReal();
751 SetSize(new Vector3(0.45f,0.6f, (float)data["height"].AsReal()));
752  
753 try
754 {
755 // Wearables
756 SetDefaultWearables();
757 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
758 {
759 OSDArray wears = (OSDArray)(data["wearables"]);
760 for (int i = 0; i < wears.Count; i++)
761 m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
762 }
763 else
764 {
765 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables");
766 }
767  
768 // Avatar Textures
769 SetDefaultTexture();
770 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
771 {
772 OSDArray textures = (OSDArray)(data["textures"]);
773 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
774 {
775 UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
776 if (textures[i] != null)
777 textureID = textures[i].AsUUID();
778 m_texture.CreateFace((uint)i).TextureID = new UUID(textureID);
779 }
780 }
781 else
782 {
783 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
784 }
785  
786 // Visual Parameters
787 SetDefaultParams();
788 if ((data != null) && (data["visualparams"] != null))
789 {
790 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
791 m_visualparams = data["visualparams"].AsBinary();
792 }
793 else
794 {
795 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack visual parameters");
796 }
797  
798 // Attachments
799 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
800 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
801 {
802 OSDArray attachs = (OSDArray)(data["attachments"]);
803 for (int i = 0; i < attachs.Count; i++)
804 {
805 AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
806 AppendAttachment(att);
807  
808 // m_log.DebugFormat(
809 // "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
810 // att.ItemID, att.AssetID, att.AttachPoint);
811 }
812 }
813 }
814 catch (Exception e)
815 {
816 m_log.ErrorFormat("[AVATAR APPEARANCE]: unpack failed badly: {0}{1}", e.Message, e.StackTrace);
817 }
818 }
819  
820 #endregion
821  
822 #region VPElement
823  
824 /// <summary>
825 /// Viewer Params Array Element for AgentSetAppearance
826 /// Generated from LibOMV's Visual Params list
827 /// </summary>
828 public enum VPElement : int
829 {
830 /// <summary>
831 /// Brow Size - Small 0--+255 Large
832 /// </summary>
833 SHAPE_BIG_BROW = 0,
834 /// <summary>
835 /// Nose Size - Small 0--+255 Large
836 /// </summary>
837 SHAPE_NOSE_BIG_OUT = 1,
838 /// <summary>
839 /// Nostril Width - Narrow 0--+255 Broad
840 /// </summary>
841 SHAPE_BROAD_NOSTRILS = 2,
842 /// <summary>
843 /// Chin Cleft - Round 0--+255 Cleft
844 /// </summary>
845 SHAPE_CLEFT_CHIN = 3,
846 /// <summary>
847 /// Nose Tip Shape - Pointy 0--+255 Bulbous
848 /// </summary>
849 SHAPE_BULBOUS_NOSE_TIP = 4,
850 /// <summary>
851 /// Chin Angle - Chin Out 0--+255 Chin In
852 /// </summary>
853 SHAPE_WEAK_CHIN = 5,
854 /// <summary>
855 /// Chin-Neck - Tight Chin 0--+255 Double Chin
856 /// </summary>
857 SHAPE_DOUBLE_CHIN = 6,
858 /// <summary>
859 /// Lower Cheeks - Well-Fed 0--+255 Sunken
860 /// </summary>
861 SHAPE_SUNKEN_CHEEKS = 7,
862 /// <summary>
863 /// Upper Bridge - Low 0--+255 High
864 /// </summary>
865 SHAPE_NOBLE_NOSE_BRIDGE = 8,
866 /// <summary>
867 /// - Less 0--+255 More
868 /// </summary>
869 SHAPE_JOWLS = 9,
870 /// <summary>
871 /// Upper Chin Cleft - Round 0--+255 Cleft
872 /// </summary>
873 SHAPE_CLEFT_CHIN_UPPER = 10,
874 /// <summary>
875 /// Cheek Bones - Low 0--+255 High
876 /// </summary>
877 SHAPE_HIGH_CHEEK_BONES = 11,
878 /// <summary>
879 /// Ear Angle - In 0--+255 Out
880 /// </summary>
881 SHAPE_EARS_OUT = 12,
882 /// <summary>
883 /// Eyebrow Points - Smooth 0--+255 Pointy
884 /// </summary>
885 HAIR_POINTY_EYEBROWS = 13,
886 /// <summary>
887 /// Jaw Shape - Pointy 0--+255 Square
888 /// </summary>
889 SHAPE_SQUARE_JAW = 14,
890 /// <summary>
891 /// Upper Cheeks - Thin 0--+255 Puffy
892 /// </summary>
893 SHAPE_PUFFY_UPPER_CHEEKS = 15,
894 /// <summary>
895 /// Nose Tip Angle - Downturned 0--+255 Upturned
896 /// </summary>
897 SHAPE_UPTURNED_NOSE_TIP = 16,
898 /// <summary>
899 /// Nose Thickness - Thin Nose 0--+255 Bulbous Nose
900 /// </summary>
901 SHAPE_BULBOUS_NOSE = 17,
902 /// <summary>
903 /// Upper Eyelid Fold - Uncreased 0--+255 Creased
904 /// </summary>
905 SHAPE_UPPER_EYELID_FOLD = 18,
906 /// <summary>
907 /// Attached Earlobes - Unattached 0--+255 Attached
908 /// </summary>
909 SHAPE_ATTACHED_EARLOBES = 19,
910 /// <summary>
911 /// Eye Bags - Smooth 0--+255 Baggy
912 /// </summary>
913 SHAPE_BAGGY_EYES = 20,
914 /// <summary>
915 /// Eye Opening - Narrow 0--+255 Wide
916 /// </summary>
917 SHAPE_WIDE_EYES = 21,
918 /// <summary>
919 /// Lip Cleft - Narrow 0--+255 Wide
920 /// </summary>
921 SHAPE_WIDE_LIP_CLEFT = 22,
922 /// <summary>
923 /// Bridge Width - Narrow 0--+255 Wide
924 /// </summary>
925 SHAPE_WIDE_NOSE_BRIDGE = 23,
926 /// <summary>
927 /// Eyebrow Arc - Flat 0--+255 Arced
928 /// </summary>
929 HAIR_ARCED_EYEBROWS = 24,
930 /// <summary>
931 /// Height - Short 0--+255 Tall
932 /// </summary>
933 SHAPE_HEIGHT = 25,
934 /// <summary>
935 /// Body Thickness - Body Thin 0--+255 Body Thick
936 /// </summary>
937 SHAPE_THICKNESS = 26,
938 /// <summary>
939 /// Ear Size - Small 0--+255 Large
940 /// </summary>
941 SHAPE_BIG_EARS = 27,
942 /// <summary>
943 /// Shoulders - Narrow 0--+255 Broad
944 /// </summary>
945 SHAPE_SHOULDERS = 28,
946 /// <summary>
947 /// Hip Width - Narrow 0--+255 Wide
948 /// </summary>
949 SHAPE_HIP_WIDTH = 29,
950 /// <summary>
951 /// - Short Torso 0--+255 Long Torso
952 /// </summary>
953 SHAPE_TORSO_LENGTH = 30,
954 SHAPE_MALE = 31,
955 /// <summary>
956 /// - Short 0--+255 Long
957 /// </summary>
958 GLOVES_GLOVE_LENGTH = 32,
959 /// <summary>
960 /// - Darker 0--+255 Lighter
961 /// </summary>
962 EYES_EYE_LIGHTNESS = 33,
963 /// <summary>
964 /// - Natural 0--+255 Unnatural
965 /// </summary>
966 EYES_EYE_COLOR = 34,
967 /// <summary>
968 /// - Small 0--+255 Large
969 /// </summary>
970 SHAPE_BREAST_SIZE = 35,
971 /// <summary>
972 /// - None 0--+255 Wild
973 /// </summary>
974 SKIN_RAINBOW_COLOR = 36,
975 /// <summary>
976 /// Ruddiness - Pale 0--+255 Ruddy
977 /// </summary>
978 SKIN_RED_SKIN = 37,
979 /// <summary>
980 /// - Light 0--+255 Dark
981 /// </summary>
982 SKIN_PIGMENT = 38,
983 HAIR_RAINBOW_COLOR_39 = 39,
984 /// <summary>
985 /// - No Red 0--+255 Very Red
986 /// </summary>
987 HAIR_RED_HAIR = 40,
988 /// <summary>
989 /// - Black 0--+255 Blonde
990 /// </summary>
991 HAIR_BLONDE_HAIR = 41,
992 /// <summary>
993 /// - No White 0--+255 All White
994 /// </summary>
995 HAIR_WHITE_HAIR = 42,
996 /// <summary>
997 /// - Less Rosy 0--+255 More Rosy
998 /// </summary>
999 SKIN_ROSY_COMPLEXION = 43,
1000 /// <summary>
1001 /// - Darker 0--+255 Pinker
1002 /// </summary>
1003 SKIN_LIP_PINKNESS = 44,
1004 /// <summary>
1005 /// - Thin Eyebrows 0--+255 Bushy Eyebrows
1006 /// </summary>
1007 HAIR_EYEBROW_SIZE = 45,
1008 /// <summary>
1009 /// - Short 0--+255 Long
1010 /// </summary>
1011 HAIR_FRONT_FRINGE = 46,
1012 /// <summary>
1013 /// - Short 0--+255 Long
1014 /// </summary>
1015 HAIR_SIDE_FRINGE = 47,
1016 /// <summary>
1017 /// - Short 0--+255 Long
1018 /// </summary>
1019 HAIR_BACK_FRINGE = 48,
1020 /// <summary>
1021 /// - Short 0--+255 Long
1022 /// </summary>
1023 HAIR_HAIR_FRONT = 49,
1024 /// <summary>
1025 /// - Short 0--+255 Long
1026 /// </summary>
1027 HAIR_HAIR_SIDES = 50,
1028 /// <summary>
1029 /// - Short 0--+255 Long
1030 /// </summary>
1031 HAIR_HAIR_BACK = 51,
1032 /// <summary>
1033 /// - Sweep Forward 0--+255 Sweep Back
1034 /// </summary>
1035 HAIR_HAIR_SWEEP = 52,
1036 /// <summary>
1037 /// - Left 0--+255 Right
1038 /// </summary>
1039 HAIR_HAIR_TILT = 53,
1040 /// <summary>
1041 /// Middle Part - No Part 0--+255 Part
1042 /// </summary>
1043 HAIR_HAIR_PART_MIDDLE = 54,
1044 /// <summary>
1045 /// Right Part - No Part 0--+255 Part
1046 /// </summary>
1047 HAIR_HAIR_PART_RIGHT = 55,
1048 /// <summary>
1049 /// Left Part - No Part 0--+255 Part
1050 /// </summary>
1051 HAIR_HAIR_PART_LEFT = 56,
1052 /// <summary>
1053 /// Full Hair Sides - Mowhawk 0--+255 Full Sides
1054 /// </summary>
1055 HAIR_HAIR_SIDES_FULL = 57,
1056 /// <summary>
1057 /// - Less 0--+255 More
1058 /// </summary>
1059 SKIN_BODY_DEFINITION = 58,
1060 /// <summary>
1061 /// Lip Width - Narrow Lips 0--+255 Wide Lips
1062 /// </summary>
1063 SHAPE_LIP_WIDTH = 59,
1064 /// <summary>
1065 /// - Small 0--+255 Big
1066 /// </summary>
1067 SHAPE_BELLY_SIZE = 60,
1068 /// <summary>
1069 /// - Less 0--+255 More
1070 /// </summary>
1071 SKIN_FACIAL_DEFINITION = 61,
1072 /// <summary>
1073 /// - Less 0--+255 More
1074 /// </summary>
1075 SKIN_WRINKLES = 62,
1076 /// <summary>
1077 /// - Less 0--+255 More
1078 /// </summary>
1079 SKIN_FRECKLES = 63,
1080 /// <summary>
1081 /// - Short Sideburns 0--+255 Mutton Chops
1082 /// </summary>
1083 HAIR_SIDEBURNS = 64,
1084 /// <summary>
1085 /// - Chaplin 0--+255 Handlebars
1086 /// </summary>
1087 HAIR_MOUSTACHE = 65,
1088 /// <summary>
1089 /// - Less soul 0--+255 More soul
1090 /// </summary>
1091 HAIR_SOULPATCH = 66,
1092 /// <summary>
1093 /// - Less Curtains 0--+255 More Curtains
1094 /// </summary>
1095 HAIR_CHIN_CURTAINS = 67,
1096 /// <summary>
1097 /// Rumpled Hair - Smooth Hair 0--+255 Rumpled Hair
1098 /// </summary>
1099 HAIR_HAIR_RUMPLED = 68,
1100 /// <summary>
1101 /// Big Hair Front - Less 0--+255 More
1102 /// </summary>
1103 HAIR_HAIR_BIG_FRONT = 69,
1104 /// <summary>
1105 /// Big Hair Top - Less 0--+255 More
1106 /// </summary>
1107 HAIR_HAIR_BIG_TOP = 70,
1108 /// <summary>
1109 /// Big Hair Back - Less 0--+255 More
1110 /// </summary>
1111 HAIR_HAIR_BIG_BACK = 71,
1112 /// <summary>
1113 /// Spiked Hair - No Spikes 0--+255 Big Spikes
1114 /// </summary>
1115 HAIR_HAIR_SPIKED = 72,
1116 /// <summary>
1117 /// Chin Depth - Shallow 0--+255 Deep
1118 /// </summary>
1119 SHAPE_DEEP_CHIN = 73,
1120 /// <summary>
1121 /// Part Bangs - No Part 0--+255 Part Bangs
1122 /// </summary>
1123 HAIR_BANGS_PART_MIDDLE = 74,
1124 /// <summary>
1125 /// Head Shape - More Square 0--+255 More Round
1126 /// </summary>
1127 SHAPE_HEAD_SHAPE = 75,
1128 /// <summary>
1129 /// Eye Spacing - Close Set Eyes 0--+255 Far Set Eyes
1130 /// </summary>
1131 SHAPE_EYE_SPACING = 76,
1132 /// <summary>
1133 /// - Low Heels 0--+255 High Heels
1134 /// </summary>
1135 SHOES_HEEL_HEIGHT = 77,
1136 /// <summary>
1137 /// - Low Platforms 0--+255 High Platforms
1138 /// </summary>
1139 SHOES_PLATFORM_HEIGHT = 78,
1140 /// <summary>
1141 /// - Thin Lips 0--+255 Fat Lips
1142 /// </summary>
1143 SHAPE_LIP_THICKNESS = 79,
1144 /// <summary>
1145 /// Mouth Position - High 0--+255 Low
1146 /// </summary>
1147 SHAPE_MOUTH_HEIGHT = 80,
1148 /// <summary>
1149 /// Breast Buoyancy - Less Gravity 0--+255 More Gravity
1150 /// </summary>
1151 SHAPE_BREAST_GRAVITY = 81,
1152 /// <summary>
1153 /// Platform Width - Narrow 0--+255 Wide
1154 /// </summary>
1155 SHOES_SHOE_PLATFORM_WIDTH = 82,
1156 /// <summary>
1157 /// - Pointy Heels 0--+255 Thick Heels
1158 /// </summary>
1159 SHOES_HEEL_SHAPE = 83,
1160 /// <summary>
1161 /// - Pointy 0--+255 Square
1162 /// </summary>
1163 SHOES_TOE_SHAPE = 84,
1164 /// <summary>
1165 /// Foot Size - Small 0--+255 Big
1166 /// </summary>
1167 SHAPE_FOOT_SIZE = 85,
1168 /// <summary>
1169 /// Nose Width - Narrow 0--+255 Wide
1170 /// </summary>
1171 SHAPE_WIDE_NOSE = 86,
1172 /// <summary>
1173 /// Eyelash Length - Short 0--+255 Long
1174 /// </summary>
1175 SHAPE_EYELASHES_LONG = 87,
1176 /// <summary>
1177 /// - Short 0--+255 Long
1178 /// </summary>
1179 UNDERSHIRT_SLEEVE_LENGTH = 88,
1180 /// <summary>
1181 /// - Short 0--+255 Long
1182 /// </summary>
1183 UNDERSHIRT_BOTTOM = 89,
1184 /// <summary>
1185 /// - Low 0--+255 High
1186 /// </summary>
1187 UNDERSHIRT_COLLAR_FRONT = 90,
1188 JACKET_SLEEVE_LENGTH_91 = 91,
1189 JACKET_COLLAR_FRONT_92 = 92,
1190 /// <summary>
1191 /// Jacket Length - Short 0--+255 Long
1192 /// </summary>
1193 JACKET_BOTTOM_LENGTH_LOWER = 93,
1194 /// <summary>
1195 /// Open Front - Open 0--+255 Closed
1196 /// </summary>
1197 JACKET_OPEN_JACKET = 94,
1198 /// <summary>
1199 /// - Short 0--+255 Tall
1200 /// </summary>
1201 SHOES_SHOE_HEIGHT = 95,
1202 /// <summary>
1203 /// - Short 0--+255 Long
1204 /// </summary>
1205 SOCKS_SOCKS_LENGTH = 96,
1206 /// <summary>
1207 /// - Short 0--+255 Long
1208 /// </summary>
1209 UNDERPANTS_PANTS_LENGTH = 97,
1210 /// <summary>
1211 /// - Low 0--+255 High
1212 /// </summary>
1213 UNDERPANTS_PANTS_WAIST = 98,
1214 /// <summary>
1215 /// Cuff Flare - Tight Cuffs 0--+255 Flared Cuffs
1216 /// </summary>
1217 PANTS_LEG_PANTFLAIR = 99,
1218 /// <summary>
1219 /// - More Vertical 0--+255 More Sloped
1220 /// </summary>
1221 SHAPE_FOREHEAD_ANGLE = 100,
1222 /// <summary>
1223 /// - Less Body Fat 0--+255 More Body Fat
1224 /// </summary>
1225 SHAPE_BODY_FAT = 101,
1226 /// <summary>
1227 /// Pants Crotch - High and Tight 0--+255 Low and Loose
1228 /// </summary>
1229 PANTS_LOW_CROTCH = 102,
1230 /// <summary>
1231 /// Egg Head - Chin Heavy 0--+255 Forehead Heavy
1232 /// </summary>
1233 SHAPE_EGG_HEAD = 103,
1234 /// <summary>
1235 /// Head Stretch - Squash Head 0--+255 Stretch Head
1236 /// </summary>
1237 SHAPE_SQUASH_STRETCH_HEAD = 104,
1238 /// <summary>
1239 /// Torso Muscles - Less Muscular 0--+255 More Muscular
1240 /// </summary>
1241 SHAPE_TORSO_MUSCLES = 105,
1242 /// <summary>
1243 /// Outer Eye Corner - Corner Down 0--+255 Corner Up
1244 /// </summary>
1245 SHAPE_EYELID_CORNER_UP = 106,
1246 /// <summary>
1247 /// - Less Muscular 0--+255 More Muscular
1248 /// </summary>
1249 SHAPE_LEG_MUSCLES = 107,
1250 /// <summary>
1251 /// Lip Fullness - Less Full 0--+255 More Full
1252 /// </summary>
1253 SHAPE_TALL_LIPS = 108,
1254 /// <summary>
1255 /// Toe Thickness - Flat Toe 0--+255 Thick Toe
1256 /// </summary>
1257 SHOES_SHOE_TOE_THICK = 109,
1258 /// <summary>
1259 /// Crooked Nose - Nose Left 0--+255 Nose Right
1260 /// </summary>
1261 SHAPE_CROOKED_NOSE = 110,
1262 /// <summary>
1263 /// - Corner Down 0--+255 Corner Up
1264 /// </summary>
1265 SHAPE_MOUTH_CORNER = 111,
1266 /// <summary>
1267 /// - Shear Right Up 0--+255 Shear Left Up
1268 /// </summary>
1269 SHAPE_FACE_SHEAR = 112,
1270 /// <summary>
1271 /// Shift Mouth - Shift Left 0--+255 Shift Right
1272 /// </summary>
1273 SHAPE_SHIFT_MOUTH = 113,
1274 /// <summary>
1275 /// Eye Pop - Pop Right Eye 0--+255 Pop Left Eye
1276 /// </summary>
1277 SHAPE_POP_EYE = 114,
1278 /// <summary>
1279 /// Jaw Jut - Overbite 0--+255 Underbite
1280 /// </summary>
1281 SHAPE_JAW_JUT = 115,
1282 /// <summary>
1283 /// Shear Back - Full Back 0--+255 Sheared Back
1284 /// </summary>
1285 HAIR_HAIR_SHEAR_BACK = 116,
1286 /// <summary>
1287 /// - Small Hands 0--+255 Large Hands
1288 /// </summary>
1289 SHAPE_HAND_SIZE = 117,
1290 /// <summary>
1291 /// Love Handles - Less Love 0--+255 More Love
1292 /// </summary>
1293 SHAPE_LOVE_HANDLES = 118,
1294 SHAPE_TORSO_MUSCLES_119 = 119,
1295 /// <summary>
1296 /// Head Size - Small Head 0--+255 Big Head
1297 /// </summary>
1298 SHAPE_HEAD_SIZE = 120,
1299 /// <summary>
1300 /// - Skinny Neck 0--+255 Thick Neck
1301 /// </summary>
1302 SHAPE_NECK_THICKNESS = 121,
1303 /// <summary>
1304 /// Breast Cleavage - Separate 0--+255 Join
1305 /// </summary>
1306 SHAPE_BREAST_FEMALE_CLEAVAGE = 122,
1307 /// <summary>
1308 /// Pectorals - Big Pectorals 0--+255 Sunken Chest
1309 /// </summary>
1310 SHAPE_CHEST_MALE_NO_PECS = 123,
1311 /// <summary>
1312 /// Eye Size - Beady Eyes 0--+255 Anime Eyes
1313 /// </summary>
1314 SHAPE_EYE_SIZE = 124,
1315 /// <summary>
1316 /// - Short Legs 0--+255 Long Legs
1317 /// </summary>
1318 SHAPE_LEG_LENGTH = 125,
1319 /// <summary>
1320 /// - Short Arms 0--+255 Long arms
1321 /// </summary>
1322 SHAPE_ARM_LENGTH = 126,
1323 /// <summary>
1324 /// - Pink 0--+255 Black
1325 /// </summary>
1326 SKIN_LIPSTICK_COLOR = 127,
1327 /// <summary>
1328 /// - No Lipstick 0--+255 More Lipstick
1329 /// </summary>
1330 SKIN_LIPSTICK = 128,
1331 /// <summary>
1332 /// - No Lipgloss 0--+255 Glossy
1333 /// </summary>
1334 SKIN_LIPGLOSS = 129,
1335 /// <summary>
1336 /// - No Eyeliner 0--+255 Full Eyeliner
1337 /// </summary>
1338 SKIN_EYELINER = 130,
1339 /// <summary>
1340 /// - No Blush 0--+255 More Blush
1341 /// </summary>
1342 SKIN_BLUSH = 131,
1343 /// <summary>
1344 /// - Pink 0--+255 Orange
1345 /// </summary>
1346 SKIN_BLUSH_COLOR = 132,
1347 /// <summary>
1348 /// - Clear 0--+255 Opaque
1349 /// </summary>
1350 SKIN_OUT_SHDW_OPACITY = 133,
1351 /// <summary>
1352 /// - No Eyeshadow 0--+255 More Eyeshadow
1353 /// </summary>
1354 SKIN_OUTER_SHADOW = 134,
1355 /// <summary>
1356 /// - Light 0--+255 Dark
1357 /// </summary>
1358 SKIN_OUT_SHDW_COLOR = 135,
1359 /// <summary>
1360 /// - No Eyeshadow 0--+255 More Eyeshadow
1361 /// </summary>
1362 SKIN_INNER_SHADOW = 136,
1363 /// <summary>
1364 /// - No Polish 0--+255 Painted Nails
1365 /// </summary>
1366 SKIN_NAIL_POLISH = 137,
1367 /// <summary>
1368 /// - Clear 0--+255 Opaque
1369 /// </summary>
1370 SKIN_BLUSH_OPACITY = 138,
1371 /// <summary>
1372 /// - Light 0--+255 Dark
1373 /// </summary>
1374 SKIN_IN_SHDW_COLOR = 139,
1375 /// <summary>
1376 /// - Clear 0--+255 Opaque
1377 /// </summary>
1378 SKIN_IN_SHDW_OPACITY = 140,
1379 /// <summary>
1380 /// - Dark Green 0--+255 Black
1381 /// </summary>
1382 SKIN_EYELINER_COLOR = 141,
1383 /// <summary>
1384 /// - Pink 0--+255 Black
1385 /// </summary>
1386 SKIN_NAIL_POLISH_COLOR = 142,
1387 /// <summary>
1388 /// - Sparse 0--+255 Dense
1389 /// </summary>
1390 HAIR_EYEBROW_DENSITY = 143,
1391 /// <summary>
1392 /// - 5 O'Clock Shadow 0--+255 Bushy Hair
1393 /// </summary>
1394 HAIR_HAIR_THICKNESS = 144,
1395 /// <summary>
1396 /// Saddle Bags - Less Saddle 0--+255 More Saddle
1397 /// </summary>
1398 SHAPE_SADDLEBAGS = 145,
1399 /// <summary>
1400 /// Taper Back - Wide Back 0--+255 Narrow Back
1401 /// </summary>
1402 HAIR_HAIR_TAPER_BACK = 146,
1403 /// <summary>
1404 /// Taper Front - Wide Front 0--+255 Narrow Front
1405 /// </summary>
1406 HAIR_HAIR_TAPER_FRONT = 147,
1407 /// <summary>
1408 /// - Short Neck 0--+255 Long Neck
1409 /// </summary>
1410 SHAPE_NECK_LENGTH = 148,
1411 /// <summary>
1412 /// Eyebrow Height - Higher 0--+255 Lower
1413 /// </summary>
1414 HAIR_LOWER_EYEBROWS = 149,
1415 /// <summary>
1416 /// Lower Bridge - Low 0--+255 High
1417 /// </summary>
1418 SHAPE_LOWER_BRIDGE_NOSE = 150,
1419 /// <summary>
1420 /// Nostril Division - High 0--+255 Low
1421 /// </summary>
1422 SHAPE_LOW_SEPTUM_NOSE = 151,
1423 /// <summary>
1424 /// Jaw Angle - Low Jaw 0--+255 High Jaw
1425 /// </summary>
1426 SHAPE_JAW_ANGLE = 152,
1427 /// <summary>
1428 /// Shear Front - Full Front 0--+255 Sheared Front
1429 /// </summary>
1430 HAIR_HAIR_SHEAR_FRONT = 153,
1431 /// <summary>
1432 /// - Less Volume 0--+255 More Volume
1433 /// </summary>
1434 HAIR_HAIR_VOLUME = 154,
1435 /// <summary>
1436 /// Lip Cleft Depth - Shallow 0--+255 Deep
1437 /// </summary>
1438 SHAPE_LIP_CLEFT_DEEP = 155,
1439 /// <summary>
1440 /// Puffy Eyelids - Flat 0--+255 Puffy
1441 /// </summary>
1442 SHAPE_PUFFY_LOWER_LIDS = 156,
1443 /// <summary>
1444 /// - Sunken Eyes 0--+255 Bugged Eyes
1445 /// </summary>
1446 SHAPE_EYE_DEPTH = 157,
1447 /// <summary>
1448 /// - Flat Head 0--+255 Long Head
1449 /// </summary>
1450 SHAPE_HEAD_LENGTH = 158,
1451 /// <summary>
1452 /// - Less Freckles 0--+255 More Freckles
1453 /// </summary>
1454 SKIN_BODY_FRECKLES = 159,
1455 /// <summary>
1456 /// - Low 0--+255 High
1457 /// </summary>
1458 UNDERSHIRT_COLLAR_BACK = 160,
1459 JACKET_COLLAR_BACK_161 = 161,
1460 SHIRT_COLLAR_BACK_162 = 162,
1461 /// <summary>
1462 /// - Short Pigtails 0--+255 Long Pigtails
1463 /// </summary>
1464 HAIR_PIGTAILS = 163,
1465 /// <summary>
1466 /// - Short Ponytail 0--+255 Long Ponytail
1467 /// </summary>
1468 HAIR_PONYTAIL = 164,
1469 /// <summary>
1470 /// Butt Size - Flat Butt 0--+255 Big Butt
1471 /// </summary>
1472 SHAPE_BUTT_SIZE = 165,
1473 /// <summary>
1474 /// Ear Tips - Flat 0--+255 Pointy
1475 /// </summary>
1476 SHAPE_POINTY_EARS = 166,
1477 /// <summary>
1478 /// Lip Ratio - More Upper Lip 0--+255 More Lower Lip
1479 /// </summary>
1480 SHAPE_LIP_RATIO = 167,
1481 SHIRT_SLEEVE_LENGTH_168 = 168,
1482 /// <summary>
1483 /// - Short 0--+255 Long
1484 /// </summary>
1485 SHIRT_SHIRT_BOTTOM = 169,
1486 SHIRT_COLLAR_FRONT_170 = 170,
1487 SHIRT_SHIRT_RED = 171,
1488 SHIRT_SHIRT_GREEN = 172,
1489 SHIRT_SHIRT_BLUE = 173,
1490 PANTS_PANTS_RED = 174,
1491 PANTS_PANTS_GREEN = 175,
1492 PANTS_PANTS_BLUE = 176,
1493 SHOES_SHOES_RED = 177,
1494 SHOES_SHOES_GREEN = 178,
1495 /// <summary>
1496 /// - Low 0--+255 High
1497 /// </summary>
1498 PANTS_WAIST_HEIGHT = 179,
1499 PANTS_PANTS_LENGTH_180 = 180,
1500 /// <summary>
1501 /// Pants Fit - Tight Pants 0--+255 Loose Pants
1502 /// </summary>
1503 PANTS_LOOSE_LOWER_CLOTHING = 181,
1504 SHOES_SHOES_BLUE = 182,
1505 SOCKS_SOCKS_RED = 183,
1506 SOCKS_SOCKS_GREEN = 184,
1507 SOCKS_SOCKS_BLUE = 185,
1508 UNDERSHIRT_UNDERSHIRT_RED = 186,
1509 UNDERSHIRT_UNDERSHIRT_GREEN = 187,
1510 UNDERSHIRT_UNDERSHIRT_BLUE = 188,
1511 UNDERPANTS_UNDERPANTS_RED = 189,
1512 UNDERPANTS_UNDERPANTS_GREEN = 190,
1513 UNDERPANTS_UNDERPANTS_BLUE = 191,
1514 GLOVES_GLOVES_RED = 192,
1515 /// <summary>
1516 /// Shirt Fit - Tight Shirt 0--+255 Loose Shirt
1517 /// </summary>
1518 SHIRT_LOOSE_UPPER_CLOTHING = 193,
1519 GLOVES_GLOVES_GREEN = 194,
1520 GLOVES_GLOVES_BLUE = 195,
1521 JACKET_JACKET_RED = 196,
1522 JACKET_JACKET_GREEN = 197,
1523 JACKET_JACKET_BLUE = 198,
1524 /// <summary>
1525 /// Sleeve Looseness - Tight Sleeves 0--+255 Loose Sleeves
1526 /// </summary>
1527 SHIRT_SHIRTSLEEVE_FLAIR = 199,
1528 /// <summary>
1529 /// Knee Angle - Knock Kneed 0--+255 Bow Legged
1530 /// </summary>
1531 SHAPE_BOWED_LEGS = 200,
1532 /// <summary>
1533 /// - Short hips 0--+255 Long Hips
1534 /// </summary>
1535 SHAPE_HIP_LENGTH = 201,
1536 /// <summary>
1537 /// - Fingerless 0--+255 Fingers
1538 /// </summary>
1539 GLOVES_GLOVE_FINGERS = 202,
1540 /// <summary>
1541 /// bustle skirt - no bustle 0--+255 more bustle
1542 /// </summary>
1543 SKIRT_SKIRT_BUSTLE = 203,
1544 /// <summary>
1545 /// - Short 0--+255 Long
1546 /// </summary>
1547 SKIRT_SKIRT_LENGTH = 204,
1548 /// <summary>
1549 /// - Open Front 0--+255 Closed Front
1550 /// </summary>
1551 SKIRT_SLIT_FRONT = 205,
1552 /// <summary>
1553 /// - Open Back 0--+255 Closed Back
1554 /// </summary>
1555 SKIRT_SLIT_BACK = 206,
1556 /// <summary>
1557 /// - Open Left 0--+255 Closed Left
1558 /// </summary>
1559 SKIRT_SLIT_LEFT = 207,
1560 /// <summary>
1561 /// - Open Right 0--+255 Closed Right
1562 /// </summary>
1563 SKIRT_SLIT_RIGHT = 208,
1564 /// <summary>
1565 /// Skirt Fit - Tight Skirt 0--+255 Poofy Skirt
1566 /// </summary>
1567 SKIRT_SKIRT_LOOSENESS = 209,
1568 SHIRT_SHIRT_WRINKLES = 210,
1569 PANTS_PANTS_WRINKLES = 211,
1570 /// <summary>
1571 /// Jacket Wrinkles - No Wrinkles 0--+255 Wrinkles
1572 /// </summary>
1573 JACKET_JACKET_WRINKLES = 212,
1574 /// <summary>
1575 /// Package - Coin Purse 0--+255 Duffle Bag
1576 /// </summary>
1577 SHAPE_MALE_PACKAGE = 213,
1578 /// <summary>
1579 /// Inner Eye Corner - Corner Down 0--+255 Corner Up
1580 /// </summary>
1581 SHAPE_EYELID_INNER_CORNER_UP = 214,
1582 SKIRT_SKIRT_RED = 215,
1583 SKIRT_SKIRT_GREEN = 216,
1584 SKIRT_SKIRT_BLUE = 217,
1585  
1586 /// <summary>
1587 /// Avatar Physics section. These are 0 type visual params which get transmitted.
1588 /// </summary>
1589  
1590 /// <summary>
1591 /// Breast Part 1
1592 /// </summary>
1593 BREAST_PHYSICS_MASS = 218,
1594 BREAST_PHYSICS_GRAVITY = 219,
1595 BREAST_PHYSICS_DRAG = 220,
1596 BREAST_PHYSICS_UPDOWN_MAX_EFFECT = 221,
1597 BREAST_PHYSICS_UPDOWN_SPRING = 222,
1598 BREAST_PHYSICS_UPDOWN_GAIN = 223,
1599 BREAST_PHYSICS_UPDOWN_DAMPING = 224,
1600 BREAST_PHYSICS_INOUT_MAX_EFFECT = 225,
1601 BREAST_PHYSICS_INOUT_SPRING = 226,
1602 BREAST_PHYSICS_INOUT_GAIN = 227,
1603 BREAST_PHYSICS_INOUT_DAMPING = 228,
1604 /// <summary>
1605 /// Belly
1606 /// </summary>
1607 BELLY_PHYISCS_MASS = 229,
1608 BELLY_PHYSICS_GRAVITY = 230,
1609 BELLY_PHYSICS_DRAG = 231,
1610 BELLY_PHYISCS_UPDOWN_MAX_EFFECT = 232,
1611 BELLY_PHYSICS_UPDOWN_SPRING = 233,
1612 BELLY_PHYSICS_UPDOWN_GAIN = 234,
1613 BELLY_PHYSICS_UPDOWN_DAMPING = 235,
1614  
1615 /// <summary>
1616 /// Butt
1617 /// </summary>
1618 BUTT_PHYSICS_MASS = 236,
1619 BUTT_PHYSICS_GRAVITY = 237,
1620 BUTT_PHYSICS_DRAG = 238,
1621 BUTT_PHYSICS_UPDOWN_MAX_EFFECT = 239,
1622 BUTT_PHYSICS_UPDOWN_SPRING = 240,
1623 BUTT_PHYSICS_UPDOWN_GAIN = 241,
1624 BUTT_PHYSICS_UPDOWN_DAMPING = 242,
1625 BUTT_PHYSICS_LEFTRIGHT_MAX_EFFECT = 243,
1626 BUTT_PHYSICS_LEFTRIGHT_SPRING = 244,
1627 BUTT_PHYSICS_LEFTRIGHT_GAIN = 245,
1628 BUTT_PHYSICS_LEFTRIGHT_DAMPING = 246,
1629 /// <summary>
1630 /// Breast Part 2
1631 /// </summary>
1632 BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
1633 BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
1634 BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
1635 BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250
1636 }
1637 #endregion
1638 }
1639 }