diff options
Diffstat (limited to 'OpenSim/Framework/AvatarAppearance.cs')
-rw-r--r-- | OpenSim/Framework/AvatarAppearance.cs | 230 |
1 files changed, 160 insertions, 70 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index f1713a6..a7bd398 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 = 26; |
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 = 14; | ||
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,69 @@ 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; | ||
742 | if(ctx != null) | ||
743 | sendPV8 = ctx.OutboundVersion >= 0.8; | ||
739 | 744 | ||
740 | // Wearables | 745 | // Wearables |
741 | // | 746 | OSDArray wears; |
742 | // This will send as many or as few wearables as we have, unless a count | 747 | int count; |
743 | // is given. Used for legacy (pre 0.4) versions. | 748 | if (ctx == null) |
744 | int count = ctx.WearablesCount; | 749 | count = MAXWEARABLE_LEGACY; |
745 | if (ctx.WearablesCount == -1) | 750 | else |
746 | count = m_wearables.Length; | ||
747 | OSDArray wears = new OSDArray(count); | ||
748 | for (int i = 0; i < count; i++) | ||
749 | { | 751 | { |
750 | AvatarWearable dummyWearable = new AvatarWearable(); | 752 | int wbcount = ctx.WearablesCount; |
753 | if (wbcount == -1) | ||
754 | wbcount = m_wearables.Length; | ||
751 | 755 | ||
752 | if (i < m_wearables.Length) | 756 | count = wbcount; |
753 | wears.Add(m_wearables[i].Pack()); | 757 | if(count > MAXWEARABLE_PV7) |
754 | else | 758 | { |
755 | wears.Add(dummyWearable.Pack()); | 759 | count = MAXWEARABLE_PV7; |
760 | if(sendPV8) | ||
761 | { | ||
762 | wears = new OSDArray(wbcount - MAXWEARABLE_PV7); | ||
763 | for (int i = MAXWEARABLE_PV7; i < wbcount; ++i) | ||
764 | wears.Add(m_wearables[i].Pack()); | ||
765 | |||
766 | data["wrbls8"] = wears; | ||
767 | } | ||
768 | } | ||
756 | } | 769 | } |
770 | |||
771 | wears = new OSDArray(count); | ||
772 | for (int i = 0; i < count; i++) | ||
773 | wears.Add(m_wearables[i].Pack()); | ||
757 | data["wearables"] = wears; | 774 | data["wearables"] = wears; |
758 | 775 | ||
759 | // Avatar Textures | 776 | // Avatar Textures and preferences hover |
760 | OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT); | 777 | OSDArray textures; |
761 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 778 | if (sendPV8) |
762 | { | 779 | { |
763 | if (m_texture.FaceTextures[i] != null) | 780 | byte[] te = m_texture.GetBakesBytes(); |
764 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); | 781 | data["te8"] = OSD.FromBinary(te); |
765 | else | 782 | } |
766 | textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); | 783 | else |
784 | { | ||
785 | textures = new OSDArray(TEXTURE_COUNT_PV7); | ||
786 | for (uint i = 0; i < TEXTURE_COUNT_PV7; i++) | ||
787 | textures.Add(OSD.FromUUID(m_texture.GetFace(i).TextureID)); | ||
788 | data["textures"] = textures; | ||
767 | } | 789 | } |
768 | data["textures"] = textures; | ||
769 | 790 | ||
770 | if (m_cacheitems != null) | 791 | if (m_cacheitems != null) |
771 | { | 792 | { |
772 | OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems); | 793 | OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems, 0, BAKES_COUNT_PV7); |
773 | if (baked != null) | 794 | if (baked != null && baked.Count > 0) |
774 | data["bakedcache"] = baked; | 795 | data["bakedcache"] = baked; |
796 | baked = WearableCacheItem.BakedToOSD(m_cacheitems, BAKES_COUNT_PV7, -1); | ||
797 | if (baked != null && baked.Count > 0) | ||
798 | data["bc8"] = baked; | ||
775 | } | 799 | } |
776 | 800 | ||
777 | // Visual Parameters | 801 | // Visual Parameters |
@@ -810,48 +834,88 @@ namespace OpenSim.Framework | |||
810 | OSD tmpOSD; | 834 | OSD tmpOSD; |
811 | if (data.TryGetValue("serial", out tmpOSD)) | 835 | if (data.TryGetValue("serial", out tmpOSD)) |
812 | m_serial = tmpOSD.AsInteger(); | 836 | m_serial = tmpOSD.AsInteger(); |
837 | if(data.TryGetValue("aphz", out tmpOSD)) | ||
838 | AvatarPreferencesHoverZ = (float)tmpOSD.AsReal(); | ||
813 | if (data.TryGetValue("height", out tmpOSD)) | 839 | if (data.TryGetValue("height", out tmpOSD)) |
814 | // m_avatarHeight = (float)data["height"].AsReal(); | 840 | SetSize(new Vector3(0.45f, 0.6f, (float)tmpOSD.AsReal())); |
815 | SetSize(new Vector3(0.45f,0.6f, (float)tmpOSD.AsReal())); | ||
816 | 841 | ||
817 | try | 842 | try |
818 | { | 843 | { |
819 | // Wearables | 844 | // Wearables |
845 | OSD tmpOSD8; | ||
846 | OSDArray wears8 = null; | ||
847 | int wears8Count = 0; | ||
848 | |||
849 | if (data.TryGetValue("wrbls8", out tmpOSD8) && (tmpOSD8 is OSDArray)) | ||
850 | { | ||
851 | wears8 = (OSDArray)tmpOSD; | ||
852 | wears8Count = wears8.Count; | ||
853 | } | ||
854 | |||
820 | if (data.TryGetValue("wearables", out tmpOSD) && (tmpOSD is OSDArray)) | 855 | if (data.TryGetValue("wearables", out tmpOSD) && (tmpOSD is OSDArray)) |
821 | { | 856 | { |
822 | OSDArray wears = (OSDArray)tmpOSD; | 857 | OSDArray wears = (OSDArray)tmpOSD; |
823 | m_wearables = new AvatarWearable[wears.Count]; | 858 | m_wearables = new AvatarWearable[wears.Count + wears8Count]; |
824 | 859 | ||
825 | for (int i = 0; i < wears.Count; i++) | 860 | for (int i = 0; i < wears.Count; ++i) |
826 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); | 861 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); |
862 | if (wears8Count > 0) | ||
863 | { | ||
864 | for (int i = wears.Count; i < wears8Count + wears.Count; ++i) | ||
865 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); | ||
866 | } | ||
827 | } | 867 | } |
828 | else | 868 | else |
829 | { | 869 | { |
830 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables"); | 870 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables"); |
831 | } | 871 | } |
832 | 872 | ||
833 | // Avatar Textures | ||
834 | if (data.TryGetValue("textures", out tmpOSD) && (tmpOSD is OSDArray)) | 873 | if (data.TryGetValue("textures", out tmpOSD) && (tmpOSD is OSDArray)) |
835 | { | 874 | { |
836 | OSDArray textures = (OSDArray)tmpOSD; | 875 | OSDArray textures = (OSDArray)tmpOSD; |
837 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) | 876 | for (int i = 0; i < textures.Count && i < TEXTURE_COUNT_PV7; ++i) |
838 | { | 877 | { |
839 | UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
840 | tmpOSD = textures[i]; | 878 | tmpOSD = textures[i]; |
841 | if (tmpOSD != null) | 879 | if (tmpOSD != null) |
842 | textureID = tmpOSD.AsUUID(); | 880 | m_texture.CreateFace((uint)i).TextureID = tmpOSD.AsUUID(); |
843 | m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); | ||
844 | } | 881 | } |
845 | } | 882 | } |
846 | else | 883 | if (data.TryGetValue("te8", out tmpOSD)) |
847 | { | 884 | { |
848 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); | 885 | byte[] teb = tmpOSD.AsBinary(); |
886 | Primitive.TextureEntry te = new Primitive.TextureEntry(teb, 0, teb.Length); | ||
887 | m_texture = te; | ||
849 | } | 888 | } |
850 | 889 | ||
851 | if (data.TryGetValue("bakedcache", out tmpOSD) && (tmpOSD is OSDArray)) | 890 | if (data.TryGetValue("bakedcache", out tmpOSD) && (tmpOSD is OSDArray)) |
852 | { | 891 | { |
853 | OSDArray bakedOSDArray = (OSDArray)tmpOSD; | 892 | OSDArray bakedOSDArray = (OSDArray)tmpOSD; |
854 | m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray); | 893 | m_cacheitems = WearableCacheItem.GetDefaultCacheItem(); |
894 | |||
895 | bakedOSDArray = (OSDArray)tmpOSD; | ||
896 | foreach (OSDMap item in bakedOSDArray) | ||
897 | { | ||
898 | int idx = item["textureindex"].AsInteger(); | ||
899 | if (idx < 0 || idx >= m_cacheitems.Length) | ||
900 | continue; | ||
901 | m_cacheitems[idx].CacheId = item["cacheid"].AsUUID(); | ||
902 | m_cacheitems[idx].TextureID = item["textureid"].AsUUID(); | ||
903 | m_cacheitems[idx].TextureAsset = null; | ||
904 | } | ||
905 | |||
906 | if (data.TryGetValue("bc8", out tmpOSD) && (tmpOSD is OSDArray)) | ||
907 | { | ||
908 | bakedOSDArray = (OSDArray)tmpOSD; | ||
909 | foreach (OSDMap item in bakedOSDArray) | ||
910 | { | ||
911 | int idx = item["textureindex"].AsInteger(); | ||
912 | if (idx < 0 || idx >= m_cacheitems.Length) | ||
913 | continue; | ||
914 | m_cacheitems[idx].CacheId = item["cacheid"].AsUUID(); | ||
915 | m_cacheitems[idx].TextureID = item["textureid"].AsUUID(); | ||
916 | m_cacheitems[idx].TextureAsset = null; | ||
917 | } | ||
918 | } | ||
855 | } | 919 | } |
856 | 920 | ||
857 | // Visual Parameters | 921 | // Visual Parameters |
@@ -888,6 +952,32 @@ namespace OpenSim.Framework | |||
888 | 952 | ||
889 | #endregion | 953 | #endregion |
890 | 954 | ||
955 | public bool CanTeleport(float version) | ||
956 | { | ||
957 | if (version >= 0.8) | ||
958 | return true; | ||
959 | if (m_wearables.Length <= MAXWEARABLE_PV7) | ||
960 | return true; | ||
961 | for(int i = MAXWEARABLE_PV7; i < m_wearables.Length; ++i) | ||
962 | { | ||
963 | if(m_wearables[i].Count > 0) | ||
964 | return false; | ||
965 | } | ||
966 | |||
967 | // also check baked | ||
968 | for(int i = BAKES_COUNT_PV7; i < BAKE_INDICES.Length; i++) | ||
969 | { | ||
970 | int idx = BAKE_INDICES[i]; | ||
971 | if (m_texture.FaceTextures[idx] == null) | ||
972 | continue; | ||
973 | UUID tid = m_texture.FaceTextures[idx].TextureID; | ||
974 | if(tid == AppearanceManager.DEFAULT_AVATAR_TEXTURE || tid == UUID.Zero) | ||
975 | continue; | ||
976 | return false; | ||
977 | } | ||
978 | return true; | ||
979 | } | ||
980 | |||
891 | #region VPElement | 981 | #region VPElement |
892 | 982 | ||
893 | /// <summary> | 983 | /// <summary> |