aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/AvatarAppearance.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs348
1 files changed, 252 insertions, 96 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 77a7621..3973d36 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -51,27 +51,28 @@ namespace OpenSim.Framework
51 51
52 // this is viewer capabilities and weared things dependent 52 // this is viewer capabilities and weared things dependent
53 // should be only used as initial default value ( V1 viewers ) 53 // should be only used as initial default value ( V1 viewers )
54 public readonly static int VISUALPARAM_COUNT = 218; 54 public const int VISUALPARAM_COUNT = 218;
55 55
56// public readonly static int TEXTURE_COUNT = 21 56 // regions and viewer compatibility
57 // 21 bad, make it be updated as libovm gets update 57 public readonly static int TEXTURE_COUNT = 45;
58 // also keeping in sync with it 58 public const int TEXTURE_COUNT_PV7 = 29;
59 public readonly static int TEXTURE_COUNT = Primitive.TextureEntry.MAX_FACES; 59 public const int BAKES_COUNT_PV7 = 6;
60 public const int MAXWEARABLE_PV7 = 16;
61 public const int MAXWEARABLE_LEGACY = 15;
60 62
61 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 63 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20, 40, 41, 42, 43, 44 };
62 64
63 protected int m_serial = 0; 65 protected int m_serial = 0;
64 protected byte[] m_visualparams; 66 protected byte[] m_visualparams;
65 protected Primitive.TextureEntry m_texture; 67 protected Primitive.TextureEntry m_texture;
66 protected AvatarWearable[] m_wearables; 68 protected AvatarWearable[] m_wearables;
67 protected Dictionary<int, List<AvatarAttachment>> m_attachments; 69 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
68 protected float m_avatarHeight = 0; 70 protected WearableCacheItem[] m_cacheitems;
69 protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value 71 protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value
70 protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); 72 protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
73 protected float m_avatarHeight = 0;
71 protected float m_avatarFeetOffset = 0; 74 protected float m_avatarFeetOffset = 0;
72 protected float m_avatarAnimOffset = 0; 75 protected float m_avatarAnimOffset = 0;
73 protected WearableCacheItem[] m_cacheitems;
74 protected bool m_cacheItemsDirty = true;
75 76
76 public virtual int Serial 77 public virtual int Serial
77 { 78 {
@@ -128,11 +129,7 @@ namespace OpenSim.Framework
128 set { m_cacheitems = value; } 129 set { m_cacheitems = value; }
129 } 130 }
130 131
131 public virtual bool WearableCacheItemsDirty 132 public virtual float AvatarPreferencesHoverZ { get; set; }
132 {
133 get { return m_cacheItemsDirty; }
134 set { m_cacheItemsDirty = value; }
135 }
136 133
137 public AvatarAppearance() 134 public AvatarAppearance()
138 { 135 {
@@ -204,12 +201,14 @@ namespace OpenSim.Framework
204 SetDefaultParams(); 201 SetDefaultParams();
205// SetHeight(); 202// SetHeight();
206 SetSize(new Vector3(0.45f, 0.6f, 1.9f)); 203 SetSize(new Vector3(0.45f, 0.6f, 1.9f));
204 AvatarPreferencesHoverZ = 0;
207 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 205 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
208 206
209 return; 207 return;
210 } 208 }
211 209
212 m_serial = appearance.Serial; 210 m_serial = appearance.Serial;
211 AvatarPreferencesHoverZ = appearance.AvatarPreferencesHoverZ;
213 212
214 if (copyWearables && (appearance.Wearables != null)) 213 if (copyWearables && (appearance.Wearables != null))
215 { 214 {
@@ -228,7 +227,7 @@ namespace OpenSim.Framework
228 m_texture = null; 227 m_texture = null;
229 if (appearance.Texture != null) 228 if (appearance.Texture != null)
230 { 229 {
231 byte[] tbytes = appearance.Texture.GetBytes(); 230 byte[] tbytes = appearance.Texture.GetBakesBytes();
232 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); 231 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
233 if (copyBaked && appearance.m_cacheitems != null) 232 if (copyBaked && appearance.m_cacheitems != null)
234 m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone(); 233 m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone();
@@ -295,6 +294,7 @@ namespace OpenSim.Framework
295 m_serial = 0; 294 m_serial = 0;
296 295
297 SetDefaultTexture(); 296 SetDefaultTexture();
297 AvatarPreferencesHoverZ = 0;
298 298
299 //for (int i = 0; i < BAKE_INDICES.Length; i++) 299 //for (int i = 0; i < BAKE_INDICES.Length; i++)
300 // { 300 // {
@@ -330,9 +330,6 @@ namespace OpenSim.Framework
330 protected virtual void SetDefaultTexture() 330 protected virtual void SetDefaultTexture()
331 { 331 {
332 m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); 332 m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
333
334 // for (uint i = 0; i < TEXTURE_COUNT; i++)
335 // m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
336 } 333 }
337 334
338 /// <summary> 335 /// <summary>
@@ -347,31 +344,31 @@ namespace OpenSim.Framework
347 if (textureEntry == null) 344 if (textureEntry == null)
348 return false; 345 return false;
349 346
350 // There are much simpler versions of this copy that could be
351 // made. We determine if any of the textures actually
352 // changed to know if the appearance should be saved later
353 bool changed = false; 347 bool changed = false;
354 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) 348 Primitive.TextureEntryFace newface;
355 { 349 Primitive.TextureEntryFace tmpFace;
356 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
357 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
358 350
359 if (newface == null) 351 //make sure textureEntry.DefaultTexture is the unused one(DEFAULT_AVATAR_TEXTURE).
352 Primitive.TextureEntry converted = new Primitive.TextureEntry(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
353 for (uint i = 0; i < TEXTURE_COUNT; ++i)
354 {
355 newface = textureEntry.GetFace(i);
356 if (newface.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
360 { 357 {
361 if (oldface == null) 358 tmpFace = converted.GetFace(i);
362 continue; 359 tmpFace.TextureID = newface.TextureID; // we need a full high level copy, assuming all other parameters are the same.
360 if (m_texture.FaceTextures[i] == null || newface.TextureID != m_texture.FaceTextures[i].TextureID)
361 changed = true;
363 } 362 }
364 else 363 else
365 { 364 { if (m_texture.FaceTextures[i] == null)
366 if (oldface != null && oldface.TextureID == newface.TextureID)
367 continue; 365 continue;
366 if(m_texture.FaceTextures[i].TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
367 changed = true;
368 } 368 }
369
370 changed = true;
371 } 369 }
372 370 if(changed)
373 m_texture = textureEntry; 371 m_texture = converted;
374
375 return changed; 372 return changed;
376 } 373 }
377 374
@@ -736,42 +733,130 @@ namespace OpenSim.Framework
736 733
737 data["serial"] = OSD.FromInteger(m_serial); 734 data["serial"] = OSD.FromInteger(m_serial);
738 data["height"] = OSD.FromReal(m_avatarHeight); 735 data["height"] = OSD.FromReal(m_avatarHeight);
736 data["aphz"] = OSD.FromReal(AvatarPreferencesHoverZ);
737
738 if (m_texture == null)
739 return data;
740
741 bool sendPV8 = false;
739 742
740 // Wearables 743 // Wearables
741 // 744 OSDArray wears;
742 // This will send as many or as few wearables as we have, unless a count 745 int count;
743 // is given. Used for legacy (pre 0.4) versions. 746 if (ctx == null)
744 int count = ctx.WearablesCount; 747 count = MAXWEARABLE_LEGACY;
745 if (ctx.WearablesCount == -1) 748 else
746 count = m_wearables.Length;
747 OSDArray wears = new OSDArray(count);
748 for (int i = 0; i < count; i++)
749 { 749 {
750 AvatarWearable dummyWearable = new AvatarWearable(); 750 if(ctx.OutboundVersion >= 0.8)
751 751 {
752 if (i < m_wearables.Length) 752 sendPV8 = true;
753 wears.Add(m_wearables[i].Pack()); 753 count = m_wearables.Length;
754 }
755 else if (ctx.OutboundVersion >= 0.6)
756 count = MAXWEARABLE_PV7;
754 else 757 else
755 wears.Add(dummyWearable.Pack()); 758 count = MAXWEARABLE_LEGACY;
759
760 if (sendPV8 && count > MAXWEARABLE_PV7)
761 {
762 wears = new OSDArray(count - MAXWEARABLE_PV7);
763 for (int i = MAXWEARABLE_PV7; i < count; ++i)
764 wears.Add(m_wearables[i].Pack());
765
766 data["wrbls8"] = wears;
767 count = MAXWEARABLE_PV7;
768 }
756 } 769 }
770
771 if(count > m_wearables.Length)
772 count = m_wearables.Length;
773
774 wears = new OSDArray(count);
775 for (int i = 0; i < count; ++i)
776 wears.Add(m_wearables[i].Pack());
757 data["wearables"] = wears; 777 data["wearables"] = wears;
758 778
759 // Avatar Textures 779 // Avatar Textures
760 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT); 780 OSDArray textures;
761 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) 781 if (sendPV8)
762 { 782 {
763 if (m_texture.FaceTextures[i] != null) 783 byte[] te = m_texture.GetBakesBytes();
764 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); 784 data["te8"] = OSD.FromBinary(te);
765 else 785 }
766 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); 786 else
787 {
788 textures = new OSDArray(TEXTURE_COUNT_PV7);
789 for (uint i = 0; i < TEXTURE_COUNT_PV7; ++i)
790 textures.Add(OSD.FromUUID(m_texture.GetFace(i).TextureID));
791 data["textures"] = textures;
767 } 792 }
768 data["textures"] = textures;
769 793
770 if (m_cacheitems != null) 794 if (m_cacheitems != null)
771 { 795 {
772 OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems); 796 OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems, 0, BAKES_COUNT_PV7);
773 if (baked != null) 797 if (baked != null && baked.Count > 0)
774 data["bakedcache"] = baked; 798 data["bakedcache"] = baked;
799 baked = WearableCacheItem.BakedToOSD(m_cacheitems, BAKES_COUNT_PV7, -1);
800 if (baked != null && baked.Count > 0)
801 data["bc8"] = baked;
802 }
803
804 // Visual Parameters
805 OSDBinary visualparams = new OSDBinary(m_visualparams);
806 data["visualparams"] = visualparams;
807
808 lock (m_attachments)
809 {
810 // Attachments
811 OSDArray attachs = new OSDArray(m_attachments.Count);
812 foreach (AvatarAttachment attach in GetAttachments())
813 attachs.Add(attach.Pack());
814 data["attachments"] = attachs;
815 }
816
817 return data;
818 }
819
820 public OSDMap PackForNotecard()
821 {
822 OSDMap data = new OSDMap();
823
824 data["serial"] = OSD.FromInteger(m_serial);
825 data["height"] = OSD.FromReal(m_avatarHeight);
826 data["aphz"] = OSD.FromReal(AvatarPreferencesHoverZ);
827
828 // old regions may not like missing/empty wears
829 OSDArray wears = new OSDArray(MAXWEARABLE_LEGACY);
830 for (int i = 0; i< MAXWEARABLE_LEGACY; ++i)
831 wears.Add(new OSDArray());
832 data["wearables"] = wears;
833
834 // Avatar Textures
835 OSDArray textures;
836
837 // allow old regions to still see something
838 textures = new OSDArray(TEXTURE_COUNT_PV7);
839 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
840 for (uint i = 1; i < TEXTURE_COUNT_PV7; ++i)
841 textures.Add(OSD.FromUUID(m_texture.GetFace(i).TextureID));
842 data["textures"] = textures;
843
844 bool needExtra = false;
845 for (int i = BAKES_COUNT_PV7; i < BAKE_INDICES.Length; ++i)
846 {
847 int idx = BAKE_INDICES[i];
848 if (m_texture.FaceTextures[idx] == null)
849 continue;
850 if (m_texture.FaceTextures[idx].TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE ||
851 m_texture.FaceTextures[idx].TextureID == UUID.Zero)
852 continue;
853 needExtra = true;
854 }
855
856 if (needExtra)
857 {
858 byte[] te = m_texture.GetBakesBytes();
859 data["te8"] = OSD.FromBinary(te);
775 } 860 }
776 861
777 // Visual Parameters 862 // Visual Parameters
@@ -796,62 +881,108 @@ namespace OpenSim.Framework
796 /// </summary> 881 /// </summary>
797 public void Unpack(OSDMap data) 882 public void Unpack(OSDMap data)
798 { 883 {
799 if ((data != null) && (data["serial"] != null)) 884 SetDefaultWearables();
800 m_serial = data["serial"].AsInteger(); 885 SetDefaultTexture();
801 if ((data != null) && (data["height"] != null)) 886 SetDefaultParams();
802// m_avatarHeight = (float)data["height"].AsReal(); 887 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
803 SetSize(new Vector3(0.45f,0.6f, (float)data["height"].AsReal()));
804 888
805 try 889 if(data == null)
806 { 890 {
807 // Wearables 891 m_log.Warn("[AVATAR APPEARANCE]: data to unpack is null");
808 SetDefaultWearables(); 892 return;
809 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) 893 }
810 {
811 OSDArray wears = (OSDArray)(data["wearables"]);
812 894
813 int count = wears.Count; 895 OSD tmpOSD;
896 if (data.TryGetValue("serial", out tmpOSD))
897 m_serial = tmpOSD.AsInteger();
898 if(data.TryGetValue("aphz", out tmpOSD))
899 AvatarPreferencesHoverZ = (float)tmpOSD.AsReal();
900 if (data.TryGetValue("height", out tmpOSD))
901 SetSize(new Vector3(0.45f, 0.6f, (float)tmpOSD.AsReal()));
814 902
815 m_wearables = new AvatarWearable[count]; 903 try
904 {
905 // Wearables
906 OSD tmpOSD8;
907 OSDArray wears8 = null;
908 int wears8Count = 0;
816 909
817 for (int i = 0; i < count; i++) 910 if (data.TryGetValue("wrbls8", out tmpOSD8) && (tmpOSD8 is OSDArray))
818 m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
819 }
820 else
821 { 911 {
822 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables"); 912 wears8 = (OSDArray)tmpOSD8;
913 wears8Count = wears8.Count;
823 } 914 }
824 915
825 // Avatar Textures 916 if (data.TryGetValue("wearables", out tmpOSD) && (tmpOSD is OSDArray))
826 SetDefaultTexture();
827 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
828 { 917 {
829 OSDArray textures = (OSDArray)(data["textures"]); 918 OSDArray wears = (OSDArray)tmpOSD;
830 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) 919 if(wears.Count + wears8Count > 0)
831 { 920 {
832 UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; 921 m_wearables = new AvatarWearable[wears.Count + wears8Count];
833 if (textures[i] != null) 922
834 textureID = textures[i].AsUUID(); 923 for (int i = 0; i < wears.Count; ++i)
835 m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); 924 m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
925 if (wears8Count > 0)
926 {
927 for (int i = 0; i < wears8Count; ++i)
928 m_wearables[i + wears.Count] = new AvatarWearable((OSDArray)wears8[i]);
929 }
836 } 930 }
837 } 931 }
838 else 932
933 if (data.TryGetValue("te8", out tmpOSD))
839 { 934 {
840 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); 935 byte[] teb = tmpOSD.AsBinary();
936 Primitive.TextureEntry te = new Primitive.TextureEntry(teb, 0, teb.Length);
937 m_texture = te;
938 }
939 else if (data.TryGetValue("textures", out tmpOSD) && (tmpOSD is OSDArray))
940 {
941 OSDArray textures = (OSDArray)tmpOSD;
942 for (int i = 0; i < textures.Count && i < TEXTURE_COUNT_PV7; ++i)
943 {
944 tmpOSD = textures[i];
945 if (tmpOSD != null)
946 m_texture.CreateFace((uint)i).TextureID = tmpOSD.AsUUID();
947 }
841 } 948 }
842 949
843 if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array) 950 if (data.TryGetValue("bakedcache", out tmpOSD) && (tmpOSD is OSDArray))
844 { 951 {
845 OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]); 952 OSDArray bakedOSDArray = (OSDArray)tmpOSD;
846 m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray); 953 m_cacheitems = WearableCacheItem.GetDefaultCacheItem();
954
955 bakedOSDArray = (OSDArray)tmpOSD;
956 foreach (OSDMap item in bakedOSDArray)
957 {
958 int idx = item["textureindex"].AsInteger();
959 if (idx < 0 || idx >= m_cacheitems.Length)
960 continue;
961 m_cacheitems[idx].CacheId = item["cacheid"].AsUUID();
962 m_cacheitems[idx].TextureID = item["textureid"].AsUUID();
963 m_cacheitems[idx].TextureAsset = null;
964 }
965
966 if (data.TryGetValue("bc8", out tmpOSD) && (tmpOSD is OSDArray))
967 {
968 bakedOSDArray = (OSDArray)tmpOSD;
969 foreach (OSDMap item in bakedOSDArray)
970 {
971 int idx = item["textureindex"].AsInteger();
972 if (idx < 0 || idx >= m_cacheitems.Length)
973 continue;
974 m_cacheitems[idx].CacheId = item["cacheid"].AsUUID();
975 m_cacheitems[idx].TextureID = item["textureid"].AsUUID();
976 m_cacheitems[idx].TextureAsset = null;
977 }
978 }
847 } 979 }
848 980
849 // Visual Parameters 981 // Visual Parameters
850 SetDefaultParams(); 982 if (data.TryGetValue("visualparams", out tmpOSD))
851 if ((data != null) && (data["visualparams"] != null))
852 { 983 {
853 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array)) 984 if (tmpOSD is OSDBinary || tmpOSD is OSDArray)
854 m_visualparams = data["visualparams"].AsBinary(); 985 m_visualparams = tmpOSD.AsBinary();
855 } 986 }
856 else 987 else
857 { 988 {
@@ -859,10 +990,9 @@ namespace OpenSim.Framework
859 } 990 }
860 991
861 // Attachments 992 // Attachments
862 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 993 if (data.TryGetValue("attachments", out tmpOSD) && tmpOSD is OSDArray)
863 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
864 { 994 {
865 OSDArray attachs = (OSDArray)(data["attachments"]); 995 OSDArray attachs = (OSDArray)tmpOSD;
866 for (int i = 0; i < attachs.Count; i++) 996 for (int i = 0; i < attachs.Count; i++)
867 { 997 {
868 AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]); 998 AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
@@ -882,6 +1012,32 @@ namespace OpenSim.Framework
882 1012
883 #endregion 1013 #endregion
884 1014
1015 public bool CanTeleport(float version)
1016 {
1017 if (version >= 0.8)
1018 return true;
1019 if (m_wearables.Length <= MAXWEARABLE_PV7)
1020 return true;
1021 for(int i = MAXWEARABLE_PV7; i < m_wearables.Length; ++i)
1022 {
1023 if(m_wearables[i].Count > 0)
1024 return false;
1025 }
1026
1027 // also check baked
1028 for (int i = BAKES_COUNT_PV7; i < BAKE_INDICES.Length; i++)
1029 {
1030 int idx = BAKE_INDICES[i];
1031 if (m_texture.FaceTextures[idx] == null)
1032 continue;
1033 if (m_texture.FaceTextures[idx].TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE ||
1034 m_texture.FaceTextures[idx].TextureID == UUID.Zero)
1035 continue;
1036 return false;
1037 }
1038 return true;
1039 }
1040
885 #region VPElement 1041 #region VPElement
886 1042
887 /// <summary> 1043 /// <summary>