diff options
Diffstat (limited to 'OpenSim/Framework/AvatarAppearance.cs')
-rw-r--r-- | OpenSim/Framework/AvatarAppearance.cs | 186 |
1 files changed, 95 insertions, 91 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 4738d88..a4bb765 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -143,13 +143,14 @@ namespace OpenSim.Framework | |||
143 | public readonly static int VISUALPARAM_COUNT = 218; | 143 | public readonly static int VISUALPARAM_COUNT = 218; |
144 | 144 | ||
145 | public readonly static int TEXTURE_COUNT = 21; | 145 | public readonly static int TEXTURE_COUNT = 21; |
146 | public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
146 | 147 | ||
147 | protected UUID m_owner; | 148 | protected UUID m_owner; |
148 | protected int m_serial = 1; | 149 | protected int m_serial = 1; |
149 | protected byte[] m_visualparams; | 150 | protected byte[] m_visualparams; |
150 | protected Primitive.TextureEntry m_texture; | 151 | protected Primitive.TextureEntry m_texture; |
151 | protected AvatarWearable[] m_wearables; | 152 | protected AvatarWearable[] m_wearables; |
152 | protected Dictionary<int, AvatarAttachment> m_attachments; | 153 | protected Dictionary<int, List<AvatarAttachment>> m_attachments; |
153 | protected float m_avatarHeight = 0; | 154 | protected float m_avatarHeight = 0; |
154 | protected float m_hipOffset = 0; | 155 | protected float m_hipOffset = 0; |
155 | 156 | ||
@@ -183,11 +184,6 @@ namespace OpenSim.Framework | |||
183 | set { m_wearables = value; } | 184 | set { m_wearables = value; } |
184 | } | 185 | } |
185 | 186 | ||
186 | public virtual Dictionary<int, AvatarAttachment> Attachments | ||
187 | { | ||
188 | get { return m_attachments; } | ||
189 | } | ||
190 | |||
191 | public virtual UUID BodyItem { | 187 | public virtual UUID BodyItem { |
192 | get { return m_wearables[AvatarWearable.BODY].ItemID; } | 188 | get { return m_wearables[AvatarWearable.BODY].ItemID; } |
193 | set { m_wearables[AvatarWearable.BODY].ItemID = value; } | 189 | set { m_wearables[AvatarWearable.BODY].ItemID = value; } |
@@ -336,7 +332,7 @@ namespace OpenSim.Framework | |||
336 | // DEBUG ON | 332 | // DEBUG ON |
337 | m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner); | 333 | m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner); |
338 | // DEBUG OFF | 334 | // DEBUG OFF |
339 | m_serial = 0; | 335 | m_serial = 1; |
340 | m_owner = owner; | 336 | m_owner = owner; |
341 | 337 | ||
342 | SetDefaultWearables(); | 338 | SetDefaultWearables(); |
@@ -344,7 +340,7 @@ namespace OpenSim.Framework | |||
344 | SetDefaultParams(); | 340 | SetDefaultParams(); |
345 | SetHeight(); | 341 | SetHeight(); |
346 | 342 | ||
347 | m_attachments = new Dictionary<int, AvatarAttachment>(); | 343 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
348 | } | 344 | } |
349 | 345 | ||
350 | public AvatarAppearance(UUID avatarID, OSDMap map) | 346 | public AvatarAppearance(UUID avatarID, OSDMap map) |
@@ -382,7 +378,7 @@ namespace OpenSim.Framework | |||
382 | 378 | ||
383 | SetHeight(); | 379 | SetHeight(); |
384 | 380 | ||
385 | m_attachments = new Dictionary<int, AvatarAttachment>(); | 381 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
386 | } | 382 | } |
387 | 383 | ||
388 | public AvatarAppearance(AvatarAppearance appearance) | 384 | public AvatarAppearance(AvatarAppearance appearance) |
@@ -392,7 +388,7 @@ namespace OpenSim.Framework | |||
392 | // DEBUG OFF | 388 | // DEBUG OFF |
393 | if (appearance == null) | 389 | if (appearance == null) |
394 | { | 390 | { |
395 | m_serial = 0; | 391 | m_serial = 1; |
396 | m_owner = UUID.Zero; | 392 | m_owner = UUID.Zero; |
397 | 393 | ||
398 | SetDefaultWearables(); | 394 | SetDefaultWearables(); |
@@ -400,7 +396,7 @@ namespace OpenSim.Framework | |||
400 | SetDefaultParams(); | 396 | SetDefaultParams(); |
401 | SetHeight(); | 397 | SetHeight(); |
402 | 398 | ||
403 | m_attachments = new Dictionary<int, AvatarAttachment>(); | 399 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
404 | 400 | ||
405 | return; | 401 | return; |
406 | } | 402 | } |
@@ -427,9 +423,10 @@ namespace OpenSim.Framework | |||
427 | if (appearance.VisualParams != null) | 423 | if (appearance.VisualParams != null) |
428 | m_visualparams = (byte[])appearance.VisualParams.Clone(); | 424 | m_visualparams = (byte[])appearance.VisualParams.Clone(); |
429 | 425 | ||
430 | m_attachments = new Dictionary<int, AvatarAttachment>(); | 426 | // Copy the attachment, force append mode since that ensures consistency |
431 | foreach (KeyValuePair<int, AvatarAttachment> kvp in appearance.Attachments) | 427 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
432 | m_attachments[kvp.Key] = new AvatarAttachment(kvp.Value); | 428 | foreach (AvatarAttachment attachment in appearance.GetAttachments()) |
429 | AppendAttachment(new AvatarAttachment(attachment)); | ||
433 | } | 430 | } |
434 | 431 | ||
435 | protected virtual void SetDefaultWearables() | 432 | protected virtual void SetDefaultWearables() |
@@ -449,14 +446,8 @@ namespace OpenSim.Framework | |||
449 | protected virtual void SetDefaultTexture() | 446 | protected virtual void SetDefaultTexture() |
450 | { | 447 | { |
451 | m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); | 448 | m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); |
452 | // The initialization of these seems to force a rebake regardless of whether it is needed | 449 | for (uint i = 0; i < TEXTURE_COUNT; i++) |
453 | // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); | 450 | m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); |
454 | // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; | ||
455 | // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; | ||
456 | // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77"); | ||
457 | // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B"); | ||
458 | // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010"); | ||
459 | // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011"); | ||
460 | } | 451 | } |
461 | 452 | ||
462 | /// <summary> | 453 | /// <summary> |
@@ -473,7 +464,7 @@ namespace OpenSim.Framework | |||
473 | // made. We determine if any of the textures actually | 464 | // made. We determine if any of the textures actually |
474 | // changed to know if the appearance should be saved later | 465 | // changed to know if the appearance should be saved later |
475 | bool changed = false; | 466 | bool changed = false; |
476 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 467 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) |
477 | { | 468 | { |
478 | Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; | 469 | Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; |
479 | Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; | 470 | Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; |
@@ -487,14 +478,14 @@ namespace OpenSim.Framework | |||
487 | if (oldface != null && oldface.TextureID == newface.TextureID) continue; | 478 | if (oldface != null && oldface.TextureID == newface.TextureID) continue; |
488 | } | 479 | } |
489 | 480 | ||
490 | m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null; | ||
491 | changed = true; | 481 | changed = true; |
492 | // DEBUG ON | 482 | // DEBUG ON |
493 | if (newface != null) | 483 | if (newface != null) |
494 | m_log.WarnFormat("[SCENEPRESENCE] index {0}, new texture id {1}",i,newface.TextureID); | 484 | m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID); |
495 | // DEBUG OFF | 485 | // DEBUG OFF |
496 | } | 486 | } |
497 | 487 | ||
488 | m_texture = textureEntry; | ||
498 | return changed; | 489 | return changed; |
499 | } | 490 | } |
500 | 491 | ||
@@ -517,8 +508,8 @@ namespace OpenSim.Framework | |||
517 | if (visualParams[i] != m_visualparams[i]) | 508 | if (visualParams[i] != m_visualparams[i]) |
518 | { | 509 | { |
519 | // DEBUG ON | 510 | // DEBUG ON |
520 | m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", | 511 | // m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", |
521 | i,m_visualparams[i],visualParams[i]); | 512 | // i,m_visualparams[i],visualParams[i]); |
522 | // DEBUG OFF | 513 | // DEBUG OFF |
523 | m_visualparams[i] = visualParams[i]; | 514 | m_visualparams[i] = visualParams[i]; |
524 | changed = true; | 515 | changed = true; |
@@ -569,6 +560,9 @@ namespace OpenSim.Framework | |||
569 | public override String ToString() | 560 | public override String ToString() |
570 | { | 561 | { |
571 | String s = ""; | 562 | String s = ""; |
563 | |||
564 | s += String.Format("Serial: {0}\n",m_serial); | ||
565 | |||
572 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 566 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) |
573 | if (m_texture.FaceTextures[i] != null) | 567 | if (m_texture.FaceTextures[i] != null) |
574 | s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID); | 568 | s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID); |
@@ -585,12 +579,41 @@ namespace OpenSim.Framework | |||
585 | } | 579 | } |
586 | // DEBUG OFF | 580 | // DEBUG OFF |
587 | 581 | ||
588 | public void SetAttachments(AvatarAttachment[] data) | 582 | /// <summary> |
583 | /// Get a list of the attachments, note that there may be | ||
584 | /// duplicate attachpoints | ||
585 | /// </summary> | ||
586 | public List<AvatarAttachment> GetAttachments() | ||
587 | { | ||
588 | List<AvatarAttachment> alist = new List<AvatarAttachment>(); | ||
589 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) | ||
590 | { | ||
591 | foreach (AvatarAttachment attach in kvp.Value) | ||
592 | alist.Add(new AvatarAttachment(attach)); | ||
593 | } | ||
594 | |||
595 | return alist; | ||
596 | } | ||
597 | |||
598 | internal void AppendAttachment(AvatarAttachment attach) | ||
589 | { | 599 | { |
590 | foreach (AvatarAttachment attach in data) | 600 | if (! m_attachments.ContainsKey(attach.AttachPoint)) |
591 | m_attachments[attach.AttachPoint] = new AvatarAttachment(attach); | 601 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); |
602 | m_attachments[attach.AttachPoint].Add(attach); | ||
592 | } | 603 | } |
593 | 604 | ||
605 | internal void ReplaceAttachment(AvatarAttachment attach) | ||
606 | { | ||
607 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); | ||
608 | m_attachments[attach.AttachPoint].Add(attach); | ||
609 | } | ||
610 | |||
611 | /// <summary> | ||
612 | /// Add an attachment, if the attachpoint has the | ||
613 | /// 0x80 bit set then we assume this is an append | ||
614 | /// operation otherwise we replace whatever is | ||
615 | /// currently attached at the attachpoint | ||
616 | /// </summary> | ||
594 | public void SetAttachment(int attachpoint, UUID item, UUID asset) | 617 | public void SetAttachment(int attachpoint, UUID item, UUID asset) |
595 | { | 618 | { |
596 | if (attachpoint == 0) | 619 | if (attachpoint == 0) |
@@ -603,67 +626,47 @@ namespace OpenSim.Framework | |||
603 | return; | 626 | return; |
604 | } | 627 | } |
605 | 628 | ||
606 | m_attachments[attachpoint] = new AvatarAttachment(attachpoint,item,asset); | 629 | // check if this is an append or a replace, 0x80 marks it as an append |
607 | } | 630 | if ((attachpoint & 0x80) > 0) |
608 | |||
609 | public Hashtable GetAttachments() | ||
610 | { | ||
611 | if (m_attachments.Count == 0) | ||
612 | return null; | ||
613 | |||
614 | Hashtable ret = new Hashtable(); | ||
615 | |||
616 | foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments) | ||
617 | { | 631 | { |
618 | Hashtable data = new Hashtable(); | 632 | // strip the append bit |
619 | data["item"] = kvp.Value.ItemID.ToString(); | 633 | int point = attachpoint & 0x7F; |
620 | data["asset"] = kvp.Value.AssetID.ToString(); | 634 | AppendAttachment(new AvatarAttachment(point, item, asset)); |
621 | 635 | } | |
622 | ret[kvp.Key] = data; | 636 | else |
637 | { | ||
638 | ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset)); | ||
623 | } | 639 | } |
624 | |||
625 | return ret; | ||
626 | } | ||
627 | |||
628 | public List<int> GetAttachedPoints() | ||
629 | { | ||
630 | return new List<int>(m_attachments.Keys); | ||
631 | } | ||
632 | |||
633 | public UUID GetAttachedItem(int attachpoint) | ||
634 | { | ||
635 | if (!m_attachments.ContainsKey(attachpoint)) | ||
636 | return UUID.Zero; | ||
637 | |||
638 | return m_attachments[attachpoint].ItemID; | ||
639 | } | ||
640 | |||
641 | public UUID GetAttachedAsset(int attachpoint) | ||
642 | { | ||
643 | if (!m_attachments.ContainsKey(attachpoint)) | ||
644 | return UUID.Zero; | ||
645 | |||
646 | return m_attachments[attachpoint].AssetID; | ||
647 | } | 640 | } |
648 | 641 | ||
649 | public int GetAttachpoint(UUID itemID) | 642 | public int GetAttachpoint(UUID itemID) |
650 | { | 643 | { |
651 | foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments) | 644 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
652 | { | 645 | { |
653 | if (kvp.Value.ItemID == itemID) | 646 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); |
654 | { | 647 | if (index >= 0) |
655 | return kvp.Key; | 648 | return kvp.Key; |
656 | } | ||
657 | } | 649 | } |
650 | |||
658 | return 0; | 651 | return 0; |
659 | } | 652 | } |
660 | 653 | ||
661 | public void DetachAttachment(UUID itemID) | 654 | public void DetachAttachment(UUID itemID) |
662 | { | 655 | { |
663 | int attachpoint = GetAttachpoint(itemID); | 656 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
657 | { | ||
658 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); | ||
659 | if (index >= 0) | ||
660 | { | ||
661 | // Remove it from the list of attachments at that attach point | ||
662 | m_attachments[kvp.Key].RemoveAt(index); | ||
664 | 663 | ||
665 | if (attachpoint > 0) | 664 | // And remove the list if there are no more attachments here |
666 | m_attachments.Remove(attachpoint); | 665 | if (m_attachments[kvp.Key].Count == 0) |
666 | m_attachments.Remove(kvp.Key); | ||
667 | return; | ||
668 | } | ||
669 | } | ||
667 | } | 670 | } |
668 | 671 | ||
669 | public void ClearAttachments() | 672 | public void ClearAttachments() |
@@ -671,6 +674,8 @@ namespace OpenSim.Framework | |||
671 | m_attachments.Clear(); | 674 | m_attachments.Clear(); |
672 | } | 675 | } |
673 | 676 | ||
677 | #region Packing Functions | ||
678 | |||
674 | /// <summary> | 679 | /// <summary> |
675 | /// Create an OSDMap from the appearance data | 680 | /// Create an OSDMap from the appearance data |
676 | /// </summary> | 681 | /// </summary> |
@@ -695,7 +700,7 @@ namespace OpenSim.Framework | |||
695 | if (m_texture.FaceTextures[i] != null) | 700 | if (m_texture.FaceTextures[i] != null) |
696 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); | 701 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); |
697 | else | 702 | else |
698 | textures.Add(OSD.FromUUID(UUID.Zero)); | 703 | textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); |
699 | } | 704 | } |
700 | data["textures"] = textures; | 705 | data["textures"] = textures; |
701 | 706 | ||
@@ -705,8 +710,8 @@ namespace OpenSim.Framework | |||
705 | 710 | ||
706 | // Attachments | 711 | // Attachments |
707 | OSDArray attachs = new OSDArray(m_attachments.Count); | 712 | OSDArray attachs = new OSDArray(m_attachments.Count); |
708 | foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments) | 713 | foreach (AvatarAttachment attach in GetAttachments()) |
709 | attachs.Add(kvp.Value.Pack()); | 714 | attachs.Add(attach.Pack()); |
710 | data["attachments"] = attachs; | 715 | data["attachments"] = attachs; |
711 | 716 | ||
712 | return data; | 717 | return data; |
@@ -718,8 +723,8 @@ namespace OpenSim.Framework | |||
718 | /// </summary> | 723 | /// </summary> |
719 | public void Unpack(OSDMap data) | 724 | public void Unpack(OSDMap data) |
720 | { | 725 | { |
721 | if ((data != null) && (data["appearance_serial"] != null)) | 726 | if ((data != null) && (data["serial"] != null)) |
722 | m_serial = data["appearance_serial"].AsInteger(); | 727 | m_serial = data["serial"].AsInteger(); |
723 | if ((data != null) && (data["height"] != null)) | 728 | if ((data != null) && (data["height"] != null)) |
724 | m_avatarHeight = (float)data["height"].AsReal(); | 729 | m_avatarHeight = (float)data["height"].AsReal(); |
725 | if ((data != null) && (data["hipoffset"] != null)) | 730 | if ((data != null) && (data["hipoffset"] != null)) |
@@ -747,12 +752,10 @@ namespace OpenSim.Framework | |||
747 | OSDArray textures = (OSDArray)(data["textures"]); | 752 | OSDArray textures = (OSDArray)(data["textures"]); |
748 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) | 753 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) |
749 | { | 754 | { |
755 | UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
750 | if (textures[i] != null) | 756 | if (textures[i] != null) |
751 | { | 757 | textureID = textures[i].AsUUID(); |
752 | UUID textureID = textures[i].AsUUID(); | 758 | m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); |
753 | if (textureID != UUID.Zero) | ||
754 | m_texture.CreateFace((uint)i).TextureID = textureID; | ||
755 | } | ||
756 | } | 759 | } |
757 | } | 760 | } |
758 | else | 761 | else |
@@ -773,15 +776,12 @@ namespace OpenSim.Framework | |||
773 | } | 776 | } |
774 | 777 | ||
775 | // Attachments | 778 | // Attachments |
776 | m_attachments = new Dictionary<int, AvatarAttachment>(); | 779 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
777 | if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array) | 780 | if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array) |
778 | { | 781 | { |
779 | OSDArray attachs = (OSDArray)(data["attachments"]); | 782 | OSDArray attachs = (OSDArray)(data["attachments"]); |
780 | for (int i = 0; i < attachs.Count; i++) | 783 | for (int i = 0; i < attachs.Count; i++) |
781 | { | 784 | AppendAttachment(new AvatarAttachment((OSDMap)attachs[i])); |
782 | AvatarAttachment attach = new AvatarAttachment((OSDMap)attachs[i]); | ||
783 | m_attachments[attach.AttachPoint] = attach; | ||
784 | } | ||
785 | } | 785 | } |
786 | } | 786 | } |
787 | catch (Exception e) | 787 | catch (Exception e) |
@@ -790,6 +790,9 @@ namespace OpenSim.Framework | |||
790 | } | 790 | } |
791 | } | 791 | } |
792 | 792 | ||
793 | #endregion | ||
794 | |||
795 | #region VPElement | ||
793 | 796 | ||
794 | /// <summary> | 797 | /// <summary> |
795 | /// Viewer Params Array Element for AgentSetAppearance | 798 | /// Viewer Params Array Element for AgentSetAppearance |
@@ -1553,5 +1556,6 @@ namespace OpenSim.Framework | |||
1553 | SKIRT_SKIRT_GREEN = 216, | 1556 | SKIRT_SKIRT_GREEN = 216, |
1554 | SKIRT_SKIRT_BLUE = 217 | 1557 | SKIRT_SKIRT_BLUE = 217 |
1555 | } | 1558 | } |
1559 | #endregion | ||
1556 | } | 1560 | } |
1557 | } | 1561 | } |