opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 m_attachments[attach.AttachPoint].Add(attach);
524 }
525 }
526  
527 internal void ReplaceAttachment(AvatarAttachment attach)
528 {
529 // m_log.DebugFormat(
530 // "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
531 // attach.ItemID, attach.AssetID, attach.AttachPoint);
532  
533 lock (m_attachments)
534 {
535 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
536 m_attachments[attach.AttachPoint].Add(attach);
537 }
538 }
539  
540 /// <summary>
541 /// Set an attachment
542 /// </summary>
543 /// <remarks>
544 /// If the attachpoint has the
545 /// 0x80 bit set then we assume this is an append
546 /// operation otherwise we replace whatever is
547 /// currently attached at the attachpoint
548 /// </remarks>
549 /// <param name="attachpoint"></param>
550 /// <param name="item">If UUID.Zero, then an any attachment at the attachpoint is removed.</param>
551 /// <param name="asset"></param>
552 /// <returns>
553 /// return true if something actually changed
554 /// </returns>
555 public bool SetAttachment(int attachpoint, UUID item, UUID asset)
556 {
557 // m_log.DebugFormat(
558 // "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
559 // attachpoint, item, asset);
560  
561 if (attachpoint == 0)
562 return false;
563  
564 lock (m_attachments)
565 {
566 if (item == UUID.Zero)
567 {
568 if (m_attachments.ContainsKey(attachpoint))
569 {
570 m_attachments.Remove(attachpoint);
571 return true;
572 }
573  
574 return false;
575 }
576  
577 // When a user logs in, the attachment item ids are pulled from persistence in the Avatars table. However,
578 // the asset ids are not saved. When the avatar enters a simulator the attachments are set again. If
579 // we simply perform an item check here then the asset ids (which are now present) are never set, and NPC attachments
580 // later fail unless the attachment is detached and reattached.
581 //
582 // Therefore, we will carry on with the set if the existing attachment has no asset id.
583 AvatarAttachment existingAttachment = GetAttachmentForItem(item);
584 if (existingAttachment != null)
585 {
586 // m_log.DebugFormat(
587 // "[AVATAR APPEARANCE]: Found existing attachment for {0}, asset {1} at point {2}",
588 // existingAttachment.ItemID, existingAttachment.AssetID, existingAttachment.AttachPoint);
589  
590 if (existingAttachment.AssetID != UUID.Zero && existingAttachment.AttachPoint == (attachpoint & 0x7F))
591 {
592 m_log.DebugFormat(
593 "[AVATAR APPEARANCE]: Ignoring attempt to attach an already attached item {0} at point {1}",
594 item, attachpoint);
595  
596 return false;
597 }
598 else
599 {
600 // Remove it here so that the later append does not add a second attachment but we still update
601 // the assetID
602 DetachAttachment(existingAttachment.ItemID);
603 }
604 }
605  
606 // check if this is an append or a replace, 0x80 marks it as an append
607 if ((attachpoint & 0x80) > 0)
608 {
609 // strip the append bit
610 int point = attachpoint & 0x7F;
611 AppendAttachment(new AvatarAttachment(point, item, asset));
612 }
613 else
614 {
615 ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
616 }
617 }
618  
619 return true;
620 }
621  
622 /// <summary>
623 /// If the item is already attached, return it.
624 /// </summary>
625 /// <param name="itemID"></param>
626 /// <returns>Returns null if this item is not attached.</returns>
627 public AvatarAttachment GetAttachmentForItem(UUID itemID)
628 {
629 lock (m_attachments)
630 {
631 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
632 {
633 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
634 if (index >= 0)
635 return kvp.Value[index];
636 }
637 }
638  
639 return null;
640 }
641  
642 public int GetAttachpoint(UUID itemID)
643 {
644 lock (m_attachments)
645 {
646 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
647 {
648 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
649 if (index >= 0)
650 return kvp.Key;
651 }
652 }
653 return 0;
654 }
655  
656 public bool DetachAttachment(UUID itemID)
657 {
658 lock (m_attachments)
659 {
660 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
661 {
662 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
663 if (index >= 0)
664 {
665 // m_log.DebugFormat(
666 // "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}",
667 // m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint);
668  
669 // Remove it from the list of attachments at that attach point
670 m_attachments[kvp.Key].RemoveAt(index);
671  
672 // And remove the list if there are no more attachments here
673 if (m_attachments[kvp.Key].Count == 0)
674 m_attachments.Remove(kvp.Key);
675  
676 return true;
677 }
678 }
679 }
680  
681 return false;
682 }
683  
684 public void ClearAttachments()
685 {
686 lock (m_attachments)
687 m_attachments.Clear();
688 }
689  
690 #region Packing Functions
691  
692 /// <summary>
693 /// Create an OSDMap from the appearance data
694 /// </summary>
695 public OSDMap Pack()
696 {
697 OSDMap data = new OSDMap();
698  
699 data["serial"] = OSD.FromInteger(m_serial);
700 data["height"] = OSD.FromReal(m_avatarHeight);
701  
702 // Wearables
703 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
704 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
705 wears.Add(m_wearables[i].Pack());
706 data["wearables"] = wears;
707  
708 // Avatar Textures
709 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
710 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
711 {
712 if (m_texture.FaceTextures[i] != null)
713 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
714 else
715 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
716 }
717 data["textures"] = textures;
718  
719 // Visual Parameters
720 OSDBinary visualparams = new OSDBinary(m_visualparams);
721 data["visualparams"] = visualparams;
722  
723 lock (m_attachments)
724 {
725 // Attachments
726 OSDArray attachs = new OSDArray(m_attachments.Count);
727 foreach (AvatarAttachment attach in GetAttachments())
728 attachs.Add(attach.Pack());
729 data["attachments"] = attachs;
730 }
731  
732 return data;
733 }
734  
735 /// <summary>
736 /// Unpack and OSDMap and initialize the appearance
737 /// from it
738 /// </summary>
739 public void Unpack(OSDMap data)
740 {
741 if ((data != null) && (data["serial"] != null))
742 m_serial = data["serial"].AsInteger();
743 if ((data != null) && (data["height"] != null))
744 // m_avatarHeight = (float)data["height"].AsReal();
745 SetSize(new Vector3(0.45f,0.6f, (float)data["height"].AsReal()));
746  
747 try
748 {
749 // Wearables
750 SetDefaultWearables();
751 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
752 {
753 OSDArray wears = (OSDArray)(data["wearables"]);
754 for (int i = 0; i < wears.Count; i++)
755 m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
756 }
757 else
758 {
759 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables");
760 }
761  
762 // Avatar Textures
763 SetDefaultTexture();
764 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
765 {
766 OSDArray textures = (OSDArray)(data["textures"]);
767 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
768 {
769 UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
770 if (textures[i] != null)
771 textureID = textures[i].AsUUID();
772 m_texture.CreateFace((uint)i).TextureID = new UUID(textureID);
773 }
774 }
775 else
776 {
777 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
778 }
779  
780 // Visual Parameters
781 SetDefaultParams();
782 if ((data != null) && (data["visualparams"] != null))
783 {
784 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
785 m_visualparams = data["visualparams"].AsBinary();
786 }
787 else
788 {
789 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack visual parameters");
790 }
791  
792 // Attachments
793 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
794 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
795 {
796 OSDArray attachs = (OSDArray)(data["attachments"]);
797 for (int i = 0; i < attachs.Count; i++)
798 {
799 AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
800 AppendAttachment(att);
801  
802 // m_log.DebugFormat(
803 // "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
804 // att.ItemID, att.AssetID, att.AttachPoint);
805 }
806 }
807 }
808 catch (Exception e)
809 {
810 m_log.ErrorFormat("[AVATAR APPEARANCE]: unpack failed badly: {0}{1}", e.Message, e.StackTrace);
811 }
812 }
813  
814 #endregion
815  
816 #region VPElement
817  
818 /// <summary>
819 /// Viewer Params Array Element for AgentSetAppearance
820 /// Generated from LibOMV's Visual Params list
821 /// </summary>
822 public enum VPElement : int
823 {
824 /// <summary>
825 /// Brow Size - Small 0--+255 Large
826 /// </summary>
827 SHAPE_BIG_BROW = 0,
828 /// <summary>
829 /// Nose Size - Small 0--+255 Large
830 /// </summary>
831 SHAPE_NOSE_BIG_OUT = 1,
832 /// <summary>
833 /// Nostril Width - Narrow 0--+255 Broad
834 /// </summary>
835 SHAPE_BROAD_NOSTRILS = 2,
836 /// <summary>
837 /// Chin Cleft - Round 0--+255 Cleft
838 /// </summary>
839 SHAPE_CLEFT_CHIN = 3,
840 /// <summary>
841 /// Nose Tip Shape - Pointy 0--+255 Bulbous
842 /// </summary>
843 SHAPE_BULBOUS_NOSE_TIP = 4,
844 /// <summary>
845 /// Chin Angle - Chin Out 0--+255 Chin In
846 /// </summary>
847 SHAPE_WEAK_CHIN = 5,
848 /// <summary>
849 /// Chin-Neck - Tight Chin 0--+255 Double Chin
850 /// </summary>
851 SHAPE_DOUBLE_CHIN = 6,
852 /// <summary>
853 /// Lower Cheeks - Well-Fed 0--+255 Sunken
854 /// </summary>
855 SHAPE_SUNKEN_CHEEKS = 7,
856 /// <summary>
857 /// Upper Bridge - Low 0--+255 High
858 /// </summary>
859 SHAPE_NOBLE_NOSE_BRIDGE = 8,
860 /// <summary>
861 /// - Less 0--+255 More
862 /// </summary>
863 SHAPE_JOWLS = 9,
864 /// <summary>
865 /// Upper Chin Cleft - Round 0--+255 Cleft
866 /// </summary>
867 SHAPE_CLEFT_CHIN_UPPER = 10,
868 /// <summary>
869 /// Cheek Bones - Low 0--+255 High
870 /// </summary>
871 SHAPE_HIGH_CHEEK_BONES = 11,
872 /// <summary>
873 /// Ear Angle - In 0--+255 Out
874 /// </summary>
875 SHAPE_EARS_OUT = 12,
876 /// <summary>
877 /// Eyebrow Points - Smooth 0--+255 Pointy
878 /// </summary>
879 HAIR_POINTY_EYEBROWS = 13,
880 /// <summary>
881 /// Jaw Shape - Pointy 0--+255 Square
882 /// </summary>
883 SHAPE_SQUARE_JAW = 14,
884 /// <summary>
885 /// Upper Cheeks - Thin 0--+255 Puffy
886 /// </summary>
887 SHAPE_PUFFY_UPPER_CHEEKS = 15,
888 /// <summary>
889 /// Nose Tip Angle - Downturned 0--+255 Upturned
890 /// </summary>
891 SHAPE_UPTURNED_NOSE_TIP = 16,
892 /// <summary>
893 /// Nose Thickness - Thin Nose 0--+255 Bulbous Nose
894 /// </summary>
895 SHAPE_BULBOUS_NOSE = 17,
896 /// <summary>
897 /// Upper Eyelid Fold - Uncreased 0--+255 Creased
898 /// </summary>
899 SHAPE_UPPER_EYELID_FOLD = 18,
900 /// <summary>
901 /// Attached Earlobes - Unattached 0--+255 Attached
902 /// </summary>
903 SHAPE_ATTACHED_EARLOBES = 19,
904 /// <summary>
905 /// Eye Bags - Smooth 0--+255 Baggy
906 /// </summary>
907 SHAPE_BAGGY_EYES = 20,
908 /// <summary>
909 /// Eye Opening - Narrow 0--+255 Wide
910 /// </summary>
911 SHAPE_WIDE_EYES = 21,
912 /// <summary>
913 /// Lip Cleft - Narrow 0--+255 Wide
914 /// </summary>
915 SHAPE_WIDE_LIP_CLEFT = 22,
916 /// <summary>
917 /// Bridge Width - Narrow 0--+255 Wide
918 /// </summary>
919 SHAPE_WIDE_NOSE_BRIDGE = 23,
920 /// <summary>
921 /// Eyebrow Arc - Flat 0--+255 Arced
922 /// </summary>
923 HAIR_ARCED_EYEBROWS = 24,
924 /// <summary>
925 /// Height - Short 0--+255 Tall
926 /// </summary>
927 SHAPE_HEIGHT = 25,
928 /// <summary>
929 /// Body Thickness - Body Thin 0--+255 Body Thick
930 /// </summary>
931 SHAPE_THICKNESS = 26,
932 /// <summary>
933 /// Ear Size - Small 0--+255 Large
934 /// </summary>
935 SHAPE_BIG_EARS = 27,
936 /// <summary>
937 /// Shoulders - Narrow 0--+255 Broad
938 /// </summary>
939 SHAPE_SHOULDERS = 28,
940 /// <summary>
941 /// Hip Width - Narrow 0--+255 Wide
942 /// </summary>
943 SHAPE_HIP_WIDTH = 29,
944 /// <summary>
945 /// - Short Torso 0--+255 Long Torso
946 /// </summary>
947 SHAPE_TORSO_LENGTH = 30,
948 SHAPE_MALE = 31,
949 /// <summary>
950 /// - Short 0--+255 Long
951 /// </summary>
952 GLOVES_GLOVE_LENGTH = 32,
953 /// <summary>
954 /// - Darker 0--+255 Lighter
955 /// </summary>
956 EYES_EYE_LIGHTNESS = 33,
957 /// <summary>
958 /// - Natural 0--+255 Unnatural
959 /// </summary>
960 EYES_EYE_COLOR = 34,
961 /// <summary>
962 /// - Small 0--+255 Large
963 /// </summary>
964 SHAPE_BREAST_SIZE = 35,
965 /// <summary>
966 /// - None 0--+255 Wild
967 /// </summary>
968 SKIN_RAINBOW_COLOR = 36,
969 /// <summary>
970 /// Ruddiness - Pale 0--+255 Ruddy
971 /// </summary>
972 SKIN_RED_SKIN = 37,
973 /// <summary>
974 /// - Light 0--+255 Dark
975 /// </summary>
976 SKIN_PIGMENT = 38,
977 HAIR_RAINBOW_COLOR_39 = 39,
978 /// <summary>
979 /// - No Red 0--+255 Very Red
980 /// </summary>
981 HAIR_RED_HAIR = 40,
982 /// <summary>
983 /// - Black 0--+255 Blonde
984 /// </summary>
985 HAIR_BLONDE_HAIR = 41,
986 /// <summary>
987 /// - No White 0--+255 All White
988 /// </summary>
989 HAIR_WHITE_HAIR = 42,
990 /// <summary>
991 /// - Less Rosy 0--+255 More Rosy
992 /// </summary>
993 SKIN_ROSY_COMPLEXION = 43,
994 /// <summary>
995 /// - Darker 0--+255 Pinker
996 /// </summary>
997 SKIN_LIP_PINKNESS = 44,
998 /// <summary>
999 /// - Thin Eyebrows 0--+255 Bushy Eyebrows
1000 /// </summary>
1001 HAIR_EYEBROW_SIZE = 45,
1002 /// <summary>
1003 /// - Short 0--+255 Long
1004 /// </summary>
1005 HAIR_FRONT_FRINGE = 46,
1006 /// <summary>
1007 /// - Short 0--+255 Long
1008 /// </summary>
1009 HAIR_SIDE_FRINGE = 47,
1010 /// <summary>
1011 /// - Short 0--+255 Long
1012 /// </summary>
1013 HAIR_BACK_FRINGE = 48,
1014 /// <summary>
1015 /// - Short 0--+255 Long
1016 /// </summary>
1017 HAIR_HAIR_FRONT = 49,
1018 /// <summary>
1019 /// - Short 0--+255 Long
1020 /// </summary>
1021 HAIR_HAIR_SIDES = 50,
1022 /// <summary>
1023 /// - Short 0--+255 Long
1024 /// </summary>
1025 HAIR_HAIR_BACK = 51,
1026 /// <summary>
1027 /// - Sweep Forward 0--+255 Sweep Back
1028 /// </summary>
1029 HAIR_HAIR_SWEEP = 52,
1030 /// <summary>
1031 /// - Left 0--+255 Right
1032 /// </summary>
1033 HAIR_HAIR_TILT = 53,
1034 /// <summary>
1035 /// Middle Part - No Part 0--+255 Part
1036 /// </summary>
1037 HAIR_HAIR_PART_MIDDLE = 54,
1038 /// <summary>
1039 /// Right Part - No Part 0--+255 Part
1040 /// </summary>
1041 HAIR_HAIR_PART_RIGHT = 55,
1042 /// <summary>
1043 /// Left Part - No Part 0--+255 Part
1044 /// </summary>
1045 HAIR_HAIR_PART_LEFT = 56,
1046 /// <summary>
1047 /// Full Hair Sides - Mowhawk 0--+255 Full Sides
1048 /// </summary>
1049 HAIR_HAIR_SIDES_FULL = 57,
1050 /// <summary>
1051 /// - Less 0--+255 More
1052 /// </summary>
1053 SKIN_BODY_DEFINITION = 58,
1054 /// <summary>
1055 /// Lip Width - Narrow Lips 0--+255 Wide Lips
1056 /// </summary>
1057 SHAPE_LIP_WIDTH = 59,
1058 /// <summary>
1059 /// - Small 0--+255 Big
1060 /// </summary>
1061 SHAPE_BELLY_SIZE = 60,
1062 /// <summary>
1063 /// - Less 0--+255 More
1064 /// </summary>
1065 SKIN_FACIAL_DEFINITION = 61,
1066 /// <summary>
1067 /// - Less 0--+255 More
1068 /// </summary>
1069 SKIN_WRINKLES = 62,
1070 /// <summary>
1071 /// - Less 0--+255 More
1072 /// </summary>
1073 SKIN_FRECKLES = 63,
1074 /// <summary>
1075 /// - Short Sideburns 0--+255 Mutton Chops
1076 /// </summary>
1077 HAIR_SIDEBURNS = 64,
1078 /// <summary>
1079 /// - Chaplin 0--+255 Handlebars
1080 /// </summary>
1081 HAIR_MOUSTACHE = 65,
1082 /// <summary>
1083 /// - Less soul 0--+255 More soul
1084 /// </summary>
1085 HAIR_SOULPATCH = 66,
1086 /// <summary>
1087 /// - Less Curtains 0--+255 More Curtains
1088 /// </summary>
1089 HAIR_CHIN_CURTAINS = 67,
1090 /// <summary>
1091 /// Rumpled Hair - Smooth Hair 0--+255 Rumpled Hair
1092 /// </summary>
1093 HAIR_HAIR_RUMPLED = 68,
1094 /// <summary>
1095 /// Big Hair Front - Less 0--+255 More
1096 /// </summary>
1097 HAIR_HAIR_BIG_FRONT = 69,
1098 /// <summary>
1099 /// Big Hair Top - Less 0--+255 More
1100 /// </summary>
1101 HAIR_HAIR_BIG_TOP = 70,
1102 /// <summary>
1103 /// Big Hair Back - Less 0--+255 More
1104 /// </summary>
1105 HAIR_HAIR_BIG_BACK = 71,
1106 /// <summary>
1107 /// Spiked Hair - No Spikes 0--+255 Big Spikes
1108 /// </summary>
1109 HAIR_HAIR_SPIKED = 72,
1110 /// <summary>
1111 /// Chin Depth - Shallow 0--+255 Deep
1112 /// </summary>
1113 SHAPE_DEEP_CHIN = 73,
1114 /// <summary>
1115 /// Part Bangs - No Part 0--+255 Part Bangs
1116 /// </summary>
1117 HAIR_BANGS_PART_MIDDLE = 74,
1118 /// <summary>
1119 /// Head Shape - More Square 0--+255 More Round
1120 /// </summary>
1121 SHAPE_HEAD_SHAPE = 75,
1122 /// <summary>
1123 /// Eye Spacing - Close Set Eyes 0--+255 Far Set Eyes
1124 /// </summary>
1125 SHAPE_EYE_SPACING = 76,
1126 /// <summary>
1127 /// - Low Heels 0--+255 High Heels
1128 /// </summary>
1129 SHOES_HEEL_HEIGHT = 77,
1130 /// <summary>
1131 /// - Low Platforms 0--+255 High Platforms
1132 /// </summary>
1133 SHOES_PLATFORM_HEIGHT = 78,
1134 /// <summary>
1135 /// - Thin Lips 0--+255 Fat Lips
1136 /// </summary>
1137 SHAPE_LIP_THICKNESS = 79,
1138 /// <summary>
1139 /// Mouth Position - High 0--+255 Low
1140 /// </summary>
1141 SHAPE_MOUTH_HEIGHT = 80,
1142 /// <summary>
1143 /// Breast Buoyancy - Less Gravity 0--+255 More Gravity
1144 /// </summary>
1145 SHAPE_BREAST_GRAVITY = 81,
1146 /// <summary>
1147 /// Platform Width - Narrow 0--+255 Wide
1148 /// </summary>
1149 SHOES_SHOE_PLATFORM_WIDTH = 82,
1150 /// <summary>
1151 /// - Pointy Heels 0--+255 Thick Heels
1152 /// </summary>
1153 SHOES_HEEL_SHAPE = 83,
1154 /// <summary>
1155 /// - Pointy 0--+255 Square
1156 /// </summary>
1157 SHOES_TOE_SHAPE = 84,
1158 /// <summary>
1159 /// Foot Size - Small 0--+255 Big
1160 /// </summary>
1161 SHAPE_FOOT_SIZE = 85,
1162 /// <summary>
1163 /// Nose Width - Narrow 0--+255 Wide
1164 /// </summary>
1165 SHAPE_WIDE_NOSE = 86,
1166 /// <summary>
1167 /// Eyelash Length - Short 0--+255 Long
1168 /// </summary>
1169 SHAPE_EYELASHES_LONG = 87,
1170 /// <summary>
1171 /// - Short 0--+255 Long
1172 /// </summary>
1173 UNDERSHIRT_SLEEVE_LENGTH = 88,
1174 /// <summary>
1175 /// - Short 0--+255 Long
1176 /// </summary>
1177 UNDERSHIRT_BOTTOM = 89,
1178 /// <summary>
1179 /// - Low 0--+255 High
1180 /// </summary>
1181 UNDERSHIRT_COLLAR_FRONT = 90,
1182 JACKET_SLEEVE_LENGTH_91 = 91,
1183 JACKET_COLLAR_FRONT_92 = 92,
1184 /// <summary>
1185 /// Jacket Length - Short 0--+255 Long
1186 /// </summary>
1187 JACKET_BOTTOM_LENGTH_LOWER = 93,
1188 /// <summary>
1189 /// Open Front - Open 0--+255 Closed
1190 /// </summary>
1191 JACKET_OPEN_JACKET = 94,
1192 /// <summary>
1193 /// - Short 0--+255 Tall
1194 /// </summary>
1195 SHOES_SHOE_HEIGHT = 95,
1196 /// <summary>
1197 /// - Short 0--+255 Long
1198 /// </summary>
1199 SOCKS_SOCKS_LENGTH = 96,
1200 /// <summary>
1201 /// - Short 0--+255 Long
1202 /// </summary>
1203 UNDERPANTS_PANTS_LENGTH = 97,
1204 /// <summary>
1205 /// - Low 0--+255 High
1206 /// </summary>
1207 UNDERPANTS_PANTS_WAIST = 98,
1208 /// <summary>
1209 /// Cuff Flare - Tight Cuffs 0--+255 Flared Cuffs
1210 /// </summary>
1211 PANTS_LEG_PANTFLAIR = 99,
1212 /// <summary>
1213 /// - More Vertical 0--+255 More Sloped
1214 /// </summary>
1215 SHAPE_FOREHEAD_ANGLE = 100,
1216 /// <summary>
1217 /// - Less Body Fat 0--+255 More Body Fat
1218 /// </summary>
1219 SHAPE_BODY_FAT = 101,
1220 /// <summary>
1221 /// Pants Crotch - High and Tight 0--+255 Low and Loose
1222 /// </summary>
1223 PANTS_LOW_CROTCH = 102,
1224 /// <summary>
1225 /// Egg Head - Chin Heavy 0--+255 Forehead Heavy
1226 /// </summary>
1227 SHAPE_EGG_HEAD = 103,
1228 /// <summary>
1229 /// Head Stretch - Squash Head 0--+255 Stretch Head
1230 /// </summary>
1231 SHAPE_SQUASH_STRETCH_HEAD = 104,
1232 /// <summary>
1233 /// Torso Muscles - Less Muscular 0--+255 More Muscular
1234 /// </summary>
1235 SHAPE_TORSO_MUSCLES = 105,
1236 /// <summary>
1237 /// Outer Eye Corner - Corner Down 0--+255 Corner Up
1238 /// </summary>
1239 SHAPE_EYELID_CORNER_UP = 106,
1240 /// <summary>
1241 /// - Less Muscular 0--+255 More Muscular
1242 /// </summary>
1243 SHAPE_LEG_MUSCLES = 107,
1244 /// <summary>
1245 /// Lip Fullness - Less Full 0--+255 More Full
1246 /// </summary>
1247 SHAPE_TALL_LIPS = 108,
1248 /// <summary>
1249 /// Toe Thickness - Flat Toe 0--+255 Thick Toe
1250 /// </summary>
1251 SHOES_SHOE_TOE_THICK = 109,
1252 /// <summary>
1253 /// Crooked Nose - Nose Left 0--+255 Nose Right
1254 /// </summary>
1255 SHAPE_CROOKED_NOSE = 110,
1256 /// <summary>
1257 /// - Corner Down 0--+255 Corner Up
1258 /// </summary>
1259 SHAPE_MOUTH_CORNER = 111,
1260 /// <summary>
1261 /// - Shear Right Up 0--+255 Shear Left Up
1262 /// </summary>
1263 SHAPE_FACE_SHEAR = 112,
1264 /// <summary>
1265 /// Shift Mouth - Shift Left 0--+255 Shift Right
1266 /// </summary>
1267 SHAPE_SHIFT_MOUTH = 113,
1268 /// <summary>
1269 /// Eye Pop - Pop Right Eye 0--+255 Pop Left Eye
1270 /// </summary>
1271 SHAPE_POP_EYE = 114,
1272 /// <summary>
1273 /// Jaw Jut - Overbite 0--+255 Underbite
1274 /// </summary>
1275 SHAPE_JAW_JUT = 115,
1276 /// <summary>
1277 /// Shear Back - Full Back 0--+255 Sheared Back
1278 /// </summary>
1279 HAIR_HAIR_SHEAR_BACK = 116,
1280 /// <summary>
1281 /// - Small Hands 0--+255 Large Hands
1282 /// </summary>
1283 SHAPE_HAND_SIZE = 117,
1284 /// <summary>
1285 /// Love Handles - Less Love 0--+255 More Love
1286 /// </summary>
1287 SHAPE_LOVE_HANDLES = 118,
1288 SHAPE_TORSO_MUSCLES_119 = 119,
1289 /// <summary>
1290 /// Head Size - Small Head 0--+255 Big Head
1291 /// </summary>
1292 SHAPE_HEAD_SIZE = 120,
1293 /// <summary>
1294 /// - Skinny Neck 0--+255 Thick Neck
1295 /// </summary>
1296 SHAPE_NECK_THICKNESS = 121,
1297 /// <summary>
1298 /// Breast Cleavage - Separate 0--+255 Join
1299 /// </summary>
1300 SHAPE_BREAST_FEMALE_CLEAVAGE = 122,
1301 /// <summary>
1302 /// Pectorals - Big Pectorals 0--+255 Sunken Chest
1303 /// </summary>
1304 SHAPE_CHEST_MALE_NO_PECS = 123,
1305 /// <summary>
1306 /// Eye Size - Beady Eyes 0--+255 Anime Eyes
1307 /// </summary>
1308 SHAPE_EYE_SIZE = 124,
1309 /// <summary>
1310 /// - Short Legs 0--+255 Long Legs
1311 /// </summary>
1312 SHAPE_LEG_LENGTH = 125,
1313 /// <summary>
1314 /// - Short Arms 0--+255 Long arms
1315 /// </summary>
1316 SHAPE_ARM_LENGTH = 126,
1317 /// <summary>
1318 /// - Pink 0--+255 Black
1319 /// </summary>
1320 SKIN_LIPSTICK_COLOR = 127,
1321 /// <summary>
1322 /// - No Lipstick 0--+255 More Lipstick
1323 /// </summary>
1324 SKIN_LIPSTICK = 128,
1325 /// <summary>
1326 /// - No Lipgloss 0--+255 Glossy
1327 /// </summary>
1328 SKIN_LIPGLOSS = 129,
1329 /// <summary>
1330 /// - No Eyeliner 0--+255 Full Eyeliner
1331 /// </summary>
1332 SKIN_EYELINER = 130,
1333 /// <summary>
1334 /// - No Blush 0--+255 More Blush
1335 /// </summary>
1336 SKIN_BLUSH = 131,
1337 /// <summary>
1338 /// - Pink 0--+255 Orange
1339 /// </summary>
1340 SKIN_BLUSH_COLOR = 132,
1341 /// <summary>
1342 /// - Clear 0--+255 Opaque
1343 /// </summary>
1344 SKIN_OUT_SHDW_OPACITY = 133,
1345 /// <summary>
1346 /// - No Eyeshadow 0--+255 More Eyeshadow
1347 /// </summary>
1348 SKIN_OUTER_SHADOW = 134,
1349 /// <summary>
1350 /// - Light 0--+255 Dark
1351 /// </summary>
1352 SKIN_OUT_SHDW_COLOR = 135,
1353 /// <summary>
1354 /// - No Eyeshadow 0--+255 More Eyeshadow
1355 /// </summary>
1356 SKIN_INNER_SHADOW = 136,
1357 /// <summary>
1358 /// - No Polish 0--+255 Painted Nails
1359 /// </summary>
1360 SKIN_NAIL_POLISH = 137,
1361 /// <summary>
1362 /// - Clear 0--+255 Opaque
1363 /// </summary>
1364 SKIN_BLUSH_OPACITY = 138,
1365 /// <summary>
1366 /// - Light 0--+255 Dark
1367 /// </summary>
1368 SKIN_IN_SHDW_COLOR = 139,
1369 /// <summary>
1370 /// - Clear 0--+255 Opaque
1371 /// </summary>
1372 SKIN_IN_SHDW_OPACITY = 140,
1373 /// <summary>
1374 /// - Dark Green 0--+255 Black
1375 /// </summary>
1376 SKIN_EYELINER_COLOR = 141,
1377 /// <summary>
1378 /// - Pink 0--+255 Black
1379 /// </summary>
1380 SKIN_NAIL_POLISH_COLOR = 142,
1381 /// <summary>
1382 /// - Sparse 0--+255 Dense
1383 /// </summary>
1384 HAIR_EYEBROW_DENSITY = 143,
1385 /// <summary>
1386 /// - 5 O'Clock Shadow 0--+255 Bushy Hair
1387 /// </summary>
1388 HAIR_HAIR_THICKNESS = 144,
1389 /// <summary>
1390 /// Saddle Bags - Less Saddle 0--+255 More Saddle
1391 /// </summary>
1392 SHAPE_SADDLEBAGS = 145,
1393 /// <summary>
1394 /// Taper Back - Wide Back 0--+255 Narrow Back
1395 /// </summary>
1396 HAIR_HAIR_TAPER_BACK = 146,
1397 /// <summary>
1398 /// Taper Front - Wide Front 0--+255 Narrow Front
1399 /// </summary>
1400 HAIR_HAIR_TAPER_FRONT = 147,
1401 /// <summary>
1402 /// - Short Neck 0--+255 Long Neck
1403 /// </summary>
1404 SHAPE_NECK_LENGTH = 148,
1405 /// <summary>
1406 /// Eyebrow Height - Higher 0--+255 Lower
1407 /// </summary>
1408 HAIR_LOWER_EYEBROWS = 149,
1409 /// <summary>
1410 /// Lower Bridge - Low 0--+255 High
1411 /// </summary>
1412 SHAPE_LOWER_BRIDGE_NOSE = 150,
1413 /// <summary>
1414 /// Nostril Division - High 0--+255 Low
1415 /// </summary>
1416 SHAPE_LOW_SEPTUM_NOSE = 151,
1417 /// <summary>
1418 /// Jaw Angle - Low Jaw 0--+255 High Jaw
1419 /// </summary>
1420 SHAPE_JAW_ANGLE = 152,
1421 /// <summary>
1422 /// Shear Front - Full Front 0--+255 Sheared Front
1423 /// </summary>
1424 HAIR_HAIR_SHEAR_FRONT = 153,
1425 /// <summary>
1426 /// - Less Volume 0--+255 More Volume
1427 /// </summary>
1428 HAIR_HAIR_VOLUME = 154,
1429 /// <summary>
1430 /// Lip Cleft Depth - Shallow 0--+255 Deep
1431 /// </summary>
1432 SHAPE_LIP_CLEFT_DEEP = 155,
1433 /// <summary>
1434 /// Puffy Eyelids - Flat 0--+255 Puffy
1435 /// </summary>
1436 SHAPE_PUFFY_LOWER_LIDS = 156,
1437 /// <summary>
1438 /// - Sunken Eyes 0--+255 Bugged Eyes
1439 /// </summary>
1440 SHAPE_EYE_DEPTH = 157,
1441 /// <summary>
1442 /// - Flat Head 0--+255 Long Head
1443 /// </summary>
1444 SHAPE_HEAD_LENGTH = 158,
1445 /// <summary>
1446 /// - Less Freckles 0--+255 More Freckles
1447 /// </summary>
1448 SKIN_BODY_FRECKLES = 159,
1449 /// <summary>
1450 /// - Low 0--+255 High
1451 /// </summary>
1452 UNDERSHIRT_COLLAR_BACK = 160,
1453 JACKET_COLLAR_BACK_161 = 161,
1454 SHIRT_COLLAR_BACK_162 = 162,
1455 /// <summary>
1456 /// - Short Pigtails 0--+255 Long Pigtails
1457 /// </summary>
1458 HAIR_PIGTAILS = 163,
1459 /// <summary>
1460 /// - Short Ponytail 0--+255 Long Ponytail
1461 /// </summary>
1462 HAIR_PONYTAIL = 164,
1463 /// <summary>
1464 /// Butt Size - Flat Butt 0--+255 Big Butt
1465 /// </summary>
1466 SHAPE_BUTT_SIZE = 165,
1467 /// <summary>
1468 /// Ear Tips - Flat 0--+255 Pointy
1469 /// </summary>
1470 SHAPE_POINTY_EARS = 166,
1471 /// <summary>
1472 /// Lip Ratio - More Upper Lip 0--+255 More Lower Lip
1473 /// </summary>
1474 SHAPE_LIP_RATIO = 167,
1475 SHIRT_SLEEVE_LENGTH_168 = 168,
1476 /// <summary>
1477 /// - Short 0--+255 Long
1478 /// </summary>
1479 SHIRT_SHIRT_BOTTOM = 169,
1480 SHIRT_COLLAR_FRONT_170 = 170,
1481 SHIRT_SHIRT_RED = 171,
1482 SHIRT_SHIRT_GREEN = 172,
1483 SHIRT_SHIRT_BLUE = 173,
1484 PANTS_PANTS_RED = 174,
1485 PANTS_PANTS_GREEN = 175,
1486 PANTS_PANTS_BLUE = 176,
1487 SHOES_SHOES_RED = 177,
1488 SHOES_SHOES_GREEN = 178,
1489 /// <summary>
1490 /// - Low 0--+255 High
1491 /// </summary>
1492 PANTS_WAIST_HEIGHT = 179,
1493 PANTS_PANTS_LENGTH_180 = 180,
1494 /// <summary>
1495 /// Pants Fit - Tight Pants 0--+255 Loose Pants
1496 /// </summary>
1497 PANTS_LOOSE_LOWER_CLOTHING = 181,
1498 SHOES_SHOES_BLUE = 182,
1499 SOCKS_SOCKS_RED = 183,
1500 SOCKS_SOCKS_GREEN = 184,
1501 SOCKS_SOCKS_BLUE = 185,
1502 UNDERSHIRT_UNDERSHIRT_RED = 186,
1503 UNDERSHIRT_UNDERSHIRT_GREEN = 187,
1504 UNDERSHIRT_UNDERSHIRT_BLUE = 188,
1505 UNDERPANTS_UNDERPANTS_RED = 189,
1506 UNDERPANTS_UNDERPANTS_GREEN = 190,
1507 UNDERPANTS_UNDERPANTS_BLUE = 191,
1508 GLOVES_GLOVES_RED = 192,
1509 /// <summary>
1510 /// Shirt Fit - Tight Shirt 0--+255 Loose Shirt
1511 /// </summary>
1512 SHIRT_LOOSE_UPPER_CLOTHING = 193,
1513 GLOVES_GLOVES_GREEN = 194,
1514 GLOVES_GLOVES_BLUE = 195,
1515 JACKET_JACKET_RED = 196,
1516 JACKET_JACKET_GREEN = 197,
1517 JACKET_JACKET_BLUE = 198,
1518 /// <summary>
1519 /// Sleeve Looseness - Tight Sleeves 0--+255 Loose Sleeves
1520 /// </summary>
1521 SHIRT_SHIRTSLEEVE_FLAIR = 199,
1522 /// <summary>
1523 /// Knee Angle - Knock Kneed 0--+255 Bow Legged
1524 /// </summary>
1525 SHAPE_BOWED_LEGS = 200,
1526 /// <summary>
1527 /// - Short hips 0--+255 Long Hips
1528 /// </summary>
1529 SHAPE_HIP_LENGTH = 201,
1530 /// <summary>
1531 /// - Fingerless 0--+255 Fingers
1532 /// </summary>
1533 GLOVES_GLOVE_FINGERS = 202,
1534 /// <summary>
1535 /// bustle skirt - no bustle 0--+255 more bustle
1536 /// </summary>
1537 SKIRT_SKIRT_BUSTLE = 203,
1538 /// <summary>
1539 /// - Short 0--+255 Long
1540 /// </summary>
1541 SKIRT_SKIRT_LENGTH = 204,
1542 /// <summary>
1543 /// - Open Front 0--+255 Closed Front
1544 /// </summary>
1545 SKIRT_SLIT_FRONT = 205,
1546 /// <summary>
1547 /// - Open Back 0--+255 Closed Back
1548 /// </summary>
1549 SKIRT_SLIT_BACK = 206,
1550 /// <summary>
1551 /// - Open Left 0--+255 Closed Left
1552 /// </summary>
1553 SKIRT_SLIT_LEFT = 207,
1554 /// <summary>
1555 /// - Open Right 0--+255 Closed Right
1556 /// </summary>
1557 SKIRT_SLIT_RIGHT = 208,
1558 /// <summary>
1559 /// Skirt Fit - Tight Skirt 0--+255 Poofy Skirt
1560 /// </summary>
1561 SKIRT_SKIRT_LOOSENESS = 209,
1562 SHIRT_SHIRT_WRINKLES = 210,
1563 PANTS_PANTS_WRINKLES = 211,
1564 /// <summary>
1565 /// Jacket Wrinkles - No Wrinkles 0--+255 Wrinkles
1566 /// </summary>
1567 JACKET_JACKET_WRINKLES = 212,
1568 /// <summary>
1569 /// Package - Coin Purse 0--+255 Duffle Bag
1570 /// </summary>
1571 SHAPE_MALE_PACKAGE = 213,
1572 /// <summary>
1573 /// Inner Eye Corner - Corner Down 0--+255 Corner Up
1574 /// </summary>
1575 SHAPE_EYELID_INNER_CORNER_UP = 214,
1576 SKIRT_SKIRT_RED = 215,
1577 SKIRT_SKIRT_GREEN = 216,
1578 SKIRT_SKIRT_BLUE = 217,
1579  
1580 /// <summary>
1581 /// Avatar Physics section. These are 0 type visual params which get transmitted.
1582 /// </summary>
1583  
1584 /// <summary>
1585 /// Breast Part 1
1586 /// </summary>
1587 BREAST_PHYSICS_MASS = 218,
1588 BREAST_PHYSICS_GRAVITY = 219,
1589 BREAST_PHYSICS_DRAG = 220,
1590 BREAST_PHYSICS_UPDOWN_MAX_EFFECT = 221,
1591 BREAST_PHYSICS_UPDOWN_SPRING = 222,
1592 BREAST_PHYSICS_UPDOWN_GAIN = 223,
1593 BREAST_PHYSICS_UPDOWN_DAMPING = 224,
1594 BREAST_PHYSICS_INOUT_MAX_EFFECT = 225,
1595 BREAST_PHYSICS_INOUT_SPRING = 226,
1596 BREAST_PHYSICS_INOUT_GAIN = 227,
1597 BREAST_PHYSICS_INOUT_DAMPING = 228,
1598 /// <summary>
1599 /// Belly
1600 /// </summary>
1601 BELLY_PHYISCS_MASS = 229,
1602 BELLY_PHYSICS_GRAVITY = 230,
1603 BELLY_PHYSICS_DRAG = 231,
1604 BELLY_PHYISCS_UPDOWN_MAX_EFFECT = 232,
1605 BELLY_PHYSICS_UPDOWN_SPRING = 233,
1606 BELLY_PHYSICS_UPDOWN_GAIN = 234,
1607 BELLY_PHYSICS_UPDOWN_DAMPING = 235,
1608  
1609 /// <summary>
1610 /// Butt
1611 /// </summary>
1612 BUTT_PHYSICS_MASS = 236,
1613 BUTT_PHYSICS_GRAVITY = 237,
1614 BUTT_PHYSICS_DRAG = 238,
1615 BUTT_PHYSICS_UPDOWN_MAX_EFFECT = 239,
1616 BUTT_PHYSICS_UPDOWN_SPRING = 240,
1617 BUTT_PHYSICS_UPDOWN_GAIN = 241,
1618 BUTT_PHYSICS_UPDOWN_DAMPING = 242,
1619 BUTT_PHYSICS_LEFTRIGHT_MAX_EFFECT = 243,
1620 BUTT_PHYSICS_LEFTRIGHT_SPRING = 244,
1621 BUTT_PHYSICS_LEFTRIGHT_GAIN = 245,
1622 BUTT_PHYSICS_LEFTRIGHT_DAMPING = 246,
1623 /// <summary>
1624 /// Breast Part 2
1625 /// </summary>
1626 BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
1627 BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
1628 BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
1629 BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250
1630 }
1631 #endregion
1632 }
1633 }