aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorJonathan Freedman2010-10-29 23:12:51 -0400
committerJonathan Freedman2010-10-29 23:12:51 -0400
commitd219317074ae8ff1665118988cecb8168ae0085e (patch)
tree89a6b01925b24f83272ec36f0b6a9c378f235d59 /OpenSim/Framework
parentMerge branch 'master' into mantis5110 (diff)
parentConfiguration of persistent baked textures and save/send delays. (diff)
downloadopensim-SC_OLD-d219317074ae8ff1665118988cecb8168ae0085e.zip
opensim-SC_OLD-d219317074ae8ff1665118988cecb8168ae0085e.tar.gz
opensim-SC_OLD-d219317074ae8ff1665118988cecb8168ae0085e.tar.bz2
opensim-SC_OLD-d219317074ae8ff1665118988cecb8168ae0085e.tar.xz
Merge branch 'master' into mantis5110
Conflicts: OpenSim/Region/Framework/Scenes/ScenePresence.cs
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs63
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs888
-rw-r--r--OpenSim/Framework/AvatarAttachment.cs78
-rw-r--r--OpenSim/Framework/AvatarWearable.cs46
-rw-r--r--OpenSim/Framework/Capabilities/Caps.cs18
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs140
-rw-r--r--OpenSim/Framework/IClientAPI.cs6
-rw-r--r--OpenSim/Framework/Tests/AgentCircuitDataTest.cs2
8 files changed, 695 insertions, 546 deletions
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index 4f89d78..640a646 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31using OpenMetaverse.StructuredData; 33using OpenMetaverse.StructuredData;
32 34
@@ -38,6 +40,12 @@ namespace OpenSim.Framework
38 /// </summary> 40 /// </summary>
39 public class AgentCircuitData 41 public class AgentCircuitData
40 { 42 {
43// DEBUG ON
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47// DEBUG OFF
48
41 /// <summary> 49 /// <summary>
42 /// Avatar Unique Agent Identifier 50 /// Avatar Unique Agent Identifier
43 /// </summary> 51 /// </summary>
@@ -198,15 +206,18 @@ namespace OpenSim.Framework
198 206
199 args["service_session_id"] = OSD.FromString(ServiceSessionID); 207 args["service_session_id"] = OSD.FromString(ServiceSessionID);
200 args["start_pos"] = OSD.FromString(startpos.ToString()); 208 args["start_pos"] = OSD.FromString(startpos.ToString());
201 args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
202 args["client_ip"] = OSD.FromString(IPAddress); 209 args["client_ip"] = OSD.FromString(IPAddress);
203 args["viewer"] = OSD.FromString(Viewer); 210 args["viewer"] = OSD.FromString(Viewer);
204 args["channel"] = OSD.FromString(Channel); 211 args["channel"] = OSD.FromString(Channel);
205 args["mac"] = OSD.FromString(Mac); 212 args["mac"] = OSD.FromString(Mac);
206 args["id0"] = OSD.FromString(Id0); 213 args["id0"] = OSD.FromString(Id0);
207 214
215 // Eventually this code should be deprecated, use full appearance
216 // packing in packed_appearance
208 if (Appearance != null) 217 if (Appearance != null)
209 { 218 {
219 args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
220
210 //System.Console.WriteLine("XXX Before packing Wearables"); 221 //System.Console.WriteLine("XXX Before packing Wearables");
211 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) 222 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
212 { 223 {
@@ -221,20 +232,25 @@ namespace OpenSim.Framework
221 } 232 }
222 233
223 //System.Console.WriteLine("XXX Before packing Attachments"); 234 //System.Console.WriteLine("XXX Before packing Attachments");
224 Dictionary<int, UUID[]> attachments = Appearance.GetAttachmentDictionary(); 235 List<AvatarAttachment> attachments = Appearance.GetAttachments();
225 if ((attachments != null) && (attachments.Count > 0)) 236 if ((attachments != null) && (attachments.Count > 0))
226 { 237 {
227 OSDArray attachs = new OSDArray(attachments.Count); 238 OSDArray attachs = new OSDArray(attachments.Count);
228 foreach (KeyValuePair<int, UUID[]> kvp in attachments) 239 foreach (AvatarAttachment attach in attachments)
229 { 240 {
230 AttachmentData adata = new AttachmentData(kvp.Key, kvp.Value[0], kvp.Value[1]); 241 attachs.Add(attach.Pack());
231 attachs.Add(adata.PackUpdateMessage());
232 //System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]); 242 //System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]);
233 } 243 }
234 args["attachments"] = attachs; 244 args["attachments"] = attachs;
235 } 245 }
236 } 246 }
237 247
248 if (Appearance != null)
249 {
250 OSDMap appmap = Appearance.Pack();
251 args["packed_appearance"] = appmap;
252 }
253
238 if (ServiceURLs != null && ServiceURLs.Count > 0) 254 if (ServiceURLs != null && ServiceURLs.Count > 0)
239 { 255 {
240 OSDArray urls = new OSDArray(ServiceURLs.Count * 2); 256 OSDArray urls = new OSDArray(ServiceURLs.Count * 2);
@@ -317,34 +333,57 @@ namespace OpenSim.Framework
317 if (args["start_pos"] != null) 333 if (args["start_pos"] != null)
318 Vector3.TryParse(args["start_pos"].AsString(), out startpos); 334 Vector3.TryParse(args["start_pos"].AsString(), out startpos);
319 335
336// DEBUG ON
337 m_log.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString());
338// DEBUG OFF
339
340 try {
341 // Unpack various appearance elements
320 Appearance = new AvatarAppearance(AgentID); 342 Appearance = new AvatarAppearance(AgentID);
343
344 // Eventually this code should be deprecated, use full appearance
345 // packing in packed_appearance
321 if (args["appearance_serial"] != null) 346 if (args["appearance_serial"] != null)
322 Appearance.Serial = args["appearance_serial"].AsInteger(); 347 Appearance.Serial = args["appearance_serial"].AsInteger();
348
323 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) 349 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
324 { 350 {
325 OSDArray wears = (OSDArray)(args["wearables"]); 351 OSDArray wears = (OSDArray)(args["wearables"]);
326 for (int i = 0; i < wears.Count / 2; i++) 352 for (int i = 0; i < wears.Count / 2; i++)
327 { 353 {
328 Appearance.Wearables[i].ItemID = wears[i*2].AsUUID(); 354 AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
329 Appearance.Wearables[i].AssetID = wears[(i*2)+1].AsUUID(); 355 Appearance.SetWearable(i,awear);
330 } 356 }
331 } 357 }
332 358
333 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) 359 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
334 { 360 {
335 OSDArray attachs = (OSDArray)(args["attachments"]); 361 OSDArray attachs = (OSDArray)(args["attachments"]);
336 AttachmentData[] attachments = new AttachmentData[attachs.Count];
337 int i = 0;
338 foreach (OSD o in attachs) 362 foreach (OSD o in attachs)
339 { 363 {
340 if (o.Type == OSDType.Map) 364 if (o.Type == OSDType.Map)
341 { 365 {
342 attachments[i++] = new AttachmentData((OSDMap)o); 366 Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
343 } 367 }
344 } 368 }
345 Appearance.SetAttachments(attachments);
346 } 369 }
347 370
371 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
372 {
373 Appearance.Unpack((OSDMap)args["packed_appearance"]);
374// DEBUG ON
375 m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
376// DEBUG OFF
377 }
378// DEBUG ON
379 else
380 m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance");
381// DEBUG OFF
382 } catch (Exception e)
383 {
384 m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message);
385 }
386
348 ServiceURLs = new Dictionary<string, object>(); 387 ServiceURLs = new Dictionary<string, object>();
349 if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array) 388 if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
350 { 389 {
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 5da8ba1..e66a1e7 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,9 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using OpenMetaverse; 32using OpenMetaverse;
33using OpenMetaverse.StructuredData;
34using log4net;
32 35
33namespace OpenSim.Framework 36namespace OpenSim.Framework
34{ 37{
@@ -37,48 +40,26 @@ namespace OpenSim.Framework
37 /// </summary> 40 /// </summary>
38 public class AvatarAppearance 41 public class AvatarAppearance
39 { 42 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 // these are guessed at by the list here -
43 // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll
44 // correct them over time for when were are wrong.
45 public readonly static int BODY = 0;
46 public readonly static int SKIN = 1;
47 public readonly static int HAIR = 2;
48 public readonly static int EYES = 3;
49 public readonly static int SHIRT = 4;
50 public readonly static int PANTS = 5;
51 public readonly static int SHOES = 6;
52 public readonly static int SOCKS = 7;
53 public readonly static int JACKET = 8;
54 public readonly static int GLOVES = 9;
55 public readonly static int UNDERSHIRT = 10;
56 public readonly static int UNDERPANTS = 11;
57 public readonly static int SKIRT = 12;
58
59 private readonly static int MAX_WEARABLES = 13;
60
61 private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
62 private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
63 private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
64 private static UUID SKIN_ITEM = new UUID("77c41e39-38f9-f75a-024e-585989bfabc9");
65 private static UUID SHIRT_ASSET = new UUID("00000000-38f9-1111-024e-222222111110");
66 private static UUID SHIRT_ITEM = new UUID("77c41e39-38f9-f75a-0000-585989bf0000");
67 private static UUID PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120");
68 private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111");
69 private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
70 private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66");
71 44
72 public readonly static int VISUALPARAM_COUNT = 218; 45 public readonly static int VISUALPARAM_COUNT = 218;
73 46
47 public readonly static int TEXTURE_COUNT = 21;
48
74 protected UUID m_owner; 49 protected UUID m_owner;
50 protected int m_serial = 1;
51 protected byte[] m_visualparams;
52 protected Primitive.TextureEntry m_texture;
53 protected AvatarWearable[] m_wearables;
54 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
55 protected float m_avatarHeight = 0;
56 protected float m_hipOffset = 0;
75 57
76 public virtual UUID Owner 58 public virtual UUID Owner
77 { 59 {
78 get { return m_owner; } 60 get { return m_owner; }
79 set { m_owner = value; } 61 set { m_owner = value; }
80 } 62 }
81 protected int m_serial = 1;
82 63
83 public virtual int Serial 64 public virtual int Serial
84 { 65 {
@@ -86,15 +67,17 @@ namespace OpenSim.Framework
86 set { m_serial = value; } 67 set { m_serial = value; }
87 } 68 }
88 69
89 protected byte[] m_visualparams;
90
91 public virtual byte[] VisualParams 70 public virtual byte[] VisualParams
92 { 71 {
93 get { return m_visualparams; } 72 get { return m_visualparams; }
94 set { m_visualparams = value; } 73 set { m_visualparams = value; }
95 } 74 }
96 75
97 protected AvatarWearable[] m_wearables; 76 public virtual Primitive.TextureEntry Texture
77 {
78 get { return m_texture; }
79 set { m_texture = value; }
80 }
98 81
99 public virtual AvatarWearable[] Wearables 82 public virtual AvatarWearable[] Wearables
100 { 83 {
@@ -103,178 +86,135 @@ namespace OpenSim.Framework
103 } 86 }
104 87
105 public virtual UUID BodyItem { 88 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 89 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 90 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 91 }
109 92
110 public virtual UUID BodyAsset { 93 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 94 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 95 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 96 }
114 97
115 public virtual UUID SkinItem { 98 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 99 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 100 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 101 }
119 102
120 public virtual UUID SkinAsset { 103 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 104 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 105 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 106 }
124 107
125 public virtual UUID HairItem { 108 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 109 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 110 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 111 }
129 112
130 public virtual UUID HairAsset { 113 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 114 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 115 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 116 }
134 117
135 public virtual UUID EyesItem { 118 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 119 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 120 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 121 }
139 122
140 public virtual UUID EyesAsset { 123 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 124 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 125 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 126 }
144 127
145 public virtual UUID ShirtItem { 128 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 129 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 130 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 131 }
149 132
150 public virtual UUID ShirtAsset { 133 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 134 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 135 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 136 }
154 137
155 public virtual UUID PantsItem { 138 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 139 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 140 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 141 }
159 142
160 public virtual UUID PantsAsset { 143 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 144 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 145 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 146 }
164 147
165 public virtual UUID ShoesItem { 148 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 149 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 150 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 151 }
169 152
170 public virtual UUID ShoesAsset { 153 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 154 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 155 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 156 }
174 157
175 public virtual UUID SocksItem { 158 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 159 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 160 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 161 }
179 162
180 public virtual UUID SocksAsset { 163 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 164 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 165 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 166 }
184 167
185 public virtual UUID JacketItem { 168 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 169 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 170 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 171 }
189 172
190 public virtual UUID JacketAsset { 173 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 174 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 175 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 176 }
194 177
195 public virtual UUID GlovesItem { 178 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 179 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 180 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 181 }
199 182
200 public virtual UUID GlovesAsset { 183 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 184 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 185 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 186 }
204 187
205 public virtual UUID UnderShirtItem { 188 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 189 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 190 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 191 }
209 192
210 public virtual UUID UnderShirtAsset { 193 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 194 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 195 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 196 }
214 197
215 public virtual UUID UnderPantsItem { 198 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 199 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 200 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 201 }
219 202
220 public virtual UUID UnderPantsAsset { 203 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 204 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 205 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 206 }
224 207
225 public virtual UUID SkirtItem { 208 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 209 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 210 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 211 }
229 212
230 public virtual UUID SkirtAsset { 213 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 214 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 215 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 }
234
235 public virtual void SetDefaultWearables()
236 {
237 m_wearables[BODY].AssetID = BODY_ASSET;
238 m_wearables[BODY].ItemID = BODY_ITEM;
239 m_wearables[SKIN].AssetID = SKIN_ASSET;
240 m_wearables[SKIN].ItemID = SKIN_ITEM;
241 m_wearables[HAIR].AssetID = HAIR_ASSET;
242 m_wearables[HAIR].ItemID = HAIR_ITEM;
243 m_wearables[SHIRT].AssetID = SHIRT_ASSET;
244 m_wearables[SHIRT].ItemID = SHIRT_ITEM;
245 m_wearables[PANTS].AssetID = PANTS_ASSET;
246 m_wearables[PANTS].ItemID = PANTS_ITEM;
247 }
248
249 public virtual void ClearWearables()
250 {
251 for (int i = 0; i < 13; i++)
252 {
253 m_wearables[i].AssetID = UUID.Zero;
254 m_wearables[i].ItemID = UUID.Zero;
255 }
256 }
257
258 public virtual void SetDefaultParams(byte[] vparams)
259 {
260 // TODO: Figure out better values then 'fat scientist 150' or 'alien 0'
261 for (int i = 0; i < VISUALPARAM_COUNT; i++)
262 {
263 vparams[i] = 150;
264 }
265 }
266
267 protected Primitive.TextureEntry m_texture;
268
269 public virtual Primitive.TextureEntry Texture
270 {
271 get { return m_texture; }
272 set { m_texture = value; }
273 } 216 }
274 217
275 protected float m_avatarHeight = 0;
276 protected float m_hipOffset = 0;
277
278 public virtual float AvatarHeight 218 public virtual float AvatarHeight
279 { 219 {
280 get { return m_avatarHeight; } 220 get { return m_avatarHeight; }
@@ -286,366 +226,301 @@ namespace OpenSim.Framework
286 get { return m_hipOffset; } 226 get { return m_hipOffset; }
287 } 227 }
288 228
289 //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues
290 /*
291 public void BuildVisualParamEnum()
292 {
293 Dictionary<string, int> IndexedParams = new Dictionary<string, int>();
294 int vpIndex = 0;
295 IndexedParams = new Dictionary<string, int>();
296
297 System.Text.StringBuilder sb = new System.Text.StringBuilder();
298
299 sb.Append("public enum VPElement: int\n");
300 sb.Append("{\n");
301 foreach (KeyValuePair<int, VisualParam> kvp in OpenMetaverse.VisualParams.Params)
302 {
303 VisualParam vp = kvp.Value;
304
305 // Only Group-0 parameters are sent in AgentSetAppearance packets
306 if (kvp.Value.Group == 0)
307 {
308
309 if (!IndexedParams.ContainsKey(vp.Name))
310 {
311
312 if (vp.Label.Length > 0 || vp.LabelMin.Length > 0 || vp.LabelMax.Length > 0)
313 {
314
315 sb.Append("/// <summary>\n");
316 if (vp.LabelMin.Length > 0 && vp.LabelMax.Length > 0)
317 sb.Append(string.Format("/// {0} - {1} 0--+255 {2}\n", vp.Label, vp.LabelMin,
318 vp.LabelMax));
319
320 else
321 sb.Append(string.Format("/// {0}\n", vp.Label));
322
323 sb.Append("/// </summary>\n");
324 }
325 sb.Append(string.Format(" {0}_{1} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"),vpIndex));
326
327 IndexedParams.Add(vp.Name, vpIndex++);
328 }
329 else
330 {
331 sb.Append(string.Format(" {0}_{1}_{2} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"), vpIndex));
332 vpIndex++;
333 //int i = 0;
334 }
335 }
336 if (vpIndex < 217)
337 sb.Append(",\n");
338 else
339 sb.Append("\n");
340
341 }
342 sb.Append("}\n");
343
344 }
345 */
346
347 public AvatarAppearance() : this(UUID.Zero) {} 229 public AvatarAppearance() : this(UUID.Zero) {}
348 230
349 public AvatarAppearance(UUID owner) 231 public AvatarAppearance(UUID owner)
350 { 232 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 233// DEBUG ON
352 for (int i = 0; i < MAX_WEARABLES; i++) 234 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
353 { 235// DEBUG OFF
354 // this makes them all null 236 m_serial = 1;
355 m_wearables[i] = new AvatarWearable();
356 }
357 m_serial = 0;
358 m_owner = owner; 237 m_owner = owner;
359 //BuildVisualParamEnum() 238
360 m_visualparams = new byte[VISUALPARAM_COUNT];
361 // This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
362 SetDefaultParams(m_visualparams);
363 SetDefaultWearables(); 239 SetDefaultWearables();
364 m_texture = GetDefaultTexture(); 240 SetDefaultTexture();
241 SetDefaultParams();
242 SetHeight();
243
244 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
365 } 245 }
366 246
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 247 public AvatarAppearance(UUID avatarID, OSDMap map)
368 { 248 {
249// DEBUG ON
250 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
251// DEBUG OFF
369 m_owner = avatarID; 252 m_owner = avatarID;
370 m_serial = 1; 253 Unpack(map);
371 m_wearables = wearables; 254 SetHeight();
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 255 }
375 256
376 /// <summary> 257 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
377 /// Set up appearance textures and avatar parameters, including a height calculation
378 /// </summary>
379 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
380 { 258 {
259// DEBUG ON
260 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
261// DEBUG OFF
262 m_serial = 1;
263 m_owner = avatarID;
264
265 if (wearables != null)
266 m_wearables = wearables;
267 else
268 SetDefaultWearables();
269
381 if (textureEntry != null) 270 if (textureEntry != null)
382 m_texture = textureEntry; 271 m_texture = textureEntry;
272 else
273 SetDefaultTexture();
274
383 if (visualParams != null) 275 if (visualParams != null)
384 m_visualparams = visualParams; 276 m_visualparams = visualParams;
277 else
278 SetDefaultParams();
385 279
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 280 SetHeight();
387 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
388 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
389 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
390 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
391 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
392 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
393 m_hipOffset = (((1.23077f // Half of avatar
394 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
395 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
396 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
397 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
398 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
399
400
401
402 //System.Console.WriteLine(">>>>>>> [APPEARANCE]: Height {0} Hip offset {1}" + m_avatarHeight + " " + m_hipOffset);
403 //m_log.Debug("------------- Set Appearance Texture ---------------");
404 //Primitive.TextureEntryFace[] faces = Texture.FaceTextures;
405 //foreach (Primitive.TextureEntryFace face in faces)
406 //{
407 // if (face != null)
408 // m_log.Debug(" ++ " + face.TextureID);
409 // else
410 // m_log.Debug(" ++ NULL ");
411 //}
412 //m_log.Debug("----------------------------");
413
414 }
415
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
417 {
418 m_wearables[wearableId] = wearable;
419 }
420 281
421 public static Primitive.TextureEntry GetDefaultTexture() 282 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
422 {
423 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
424 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
425 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
426 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
427 textu.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
428 textu.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
429 textu.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
430 textu.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
431 return textu;
432 } 283 }
433 284
434 public static byte[] GetDefaultVisualParams() 285 public AvatarAppearance(AvatarAppearance appearance)
435 { 286 {
436 byte[] visualParams; 287// DEBUG ON
437 visualParams = new byte[VISUALPARAM_COUNT]; 288 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
438 for (int i = 0; i < VISUALPARAM_COUNT; i++) 289// DEBUG OFF
290 if (appearance == null)
439 { 291 {
440 visualParams[i] = 100; 292 m_serial = 1;
441 } 293 m_owner = UUID.Zero;
442 return visualParams;
443 }
444 294
445 public override String ToString() 295 SetDefaultWearables();
446 { 296 SetDefaultTexture();
447 String s = "[Wearables] =>"; 297 SetDefaultParams();
448 s += " Body Item: " + BodyItem.ToString() + ";"; 298 SetHeight();
449 s += " Skin Item: " + SkinItem.ToString() + ";";
450 s += " Shirt Item: " + ShirtItem.ToString() + ";";
451 s += " Pants Item: " + PantsItem.ToString() + ";";
452 return s;
453 }
454 299
455 // this is used for OGS1 300 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
456 public virtual Hashtable ToHashTable()
457 {
458 Hashtable h = new Hashtable();
459 h["owner"] = Owner.ToString();
460 h["serial"] = Serial.ToString();
461 h["visual_params"] = VisualParams;
462 h["texture"] = Texture.GetBytes();
463 h["avatar_height"] = AvatarHeight.ToString();
464 h["body_item"] = BodyItem.ToString();
465 h["body_asset"] = BodyAsset.ToString();
466 h["skin_item"] = SkinItem.ToString();
467 h["skin_asset"] = SkinAsset.ToString();
468 h["hair_item"] = HairItem.ToString();
469 h["hair_asset"] = HairAsset.ToString();
470 h["eyes_item"] = EyesItem.ToString();
471 h["eyes_asset"] = EyesAsset.ToString();
472 h["shirt_item"] = ShirtItem.ToString();
473 h["shirt_asset"] = ShirtAsset.ToString();
474 h["pants_item"] = PantsItem.ToString();
475 h["pants_asset"] = PantsAsset.ToString();
476 h["shoes_item"] = ShoesItem.ToString();
477 h["shoes_asset"] = ShoesAsset.ToString();
478 h["socks_item"] = SocksItem.ToString();
479 h["socks_asset"] = SocksAsset.ToString();
480 h["jacket_item"] = JacketItem.ToString();
481 h["jacket_asset"] = JacketAsset.ToString();
482 h["gloves_item"] = GlovesItem.ToString();
483 h["gloves_asset"] = GlovesAsset.ToString();
484 h["undershirt_item"] = UnderShirtItem.ToString();
485 h["undershirt_asset"] = UnderShirtAsset.ToString();
486 h["underpants_item"] = UnderPantsItem.ToString();
487 h["underpants_asset"] = UnderPantsAsset.ToString();
488 h["skirt_item"] = SkirtItem.ToString();
489 h["skirt_asset"] = SkirtAsset.ToString();
490
491 string attachments = GetAttachmentsString();
492 if (attachments != String.Empty)
493 h["attachments"] = attachments;
494
495 return h;
496 }
497
498 public AvatarAppearance(Hashtable h)
499 {
500 Owner = new UUID((string)h["owner"]);
501 Serial = Convert.ToInt32((string)h["serial"]);
502 VisualParams = (byte[])h["visual_params"];
503 301
504 if (h.Contains("texture")) 302 return;
505 {
506 byte[] te = h["texture"] as byte[];
507 if (te != null && te.Length > 0)
508 Texture = new Primitive.TextureEntry(te, 0, te.Length);
509 }
510 else
511 {
512 // We shouldn't be receiving appearance hashtables without a TextureEntry,
513 // but in case we do this will prevent a failure when saving to the database
514 Texture = GetDefaultTexture();
515 } 303 }
516
517 304
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 305 m_serial = appearance.Serial;
306 m_owner = appearance.Owner;
519 307
520 m_wearables = new AvatarWearable[MAX_WEARABLES]; 308 m_wearables = null;
521 for (int i = 0; i < MAX_WEARABLES; i++) 309 if (appearance.Wearables != null)
522 { 310 {
523 // this makes them all null 311 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
524 m_wearables[i] = new AvatarWearable(); 312 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
313 SetWearable(i,appearance.Wearables[i]);
525 } 314 }
526 315
527 BodyItem = new UUID((string)h["body_item"]); 316 m_texture = null;
528 BodyAsset = new UUID((string)h["body_asset"]); 317 if (appearance.Texture != null)
529 SkinItem = new UUID((string)h["skin_item"]);
530 SkinAsset = new UUID((string)h["skin_asset"]);
531 HairItem = new UUID((string)h["hair_item"]);
532 HairAsset = new UUID((string)h["hair_asset"]);
533 EyesItem = new UUID((string)h["eyes_item"]);
534 EyesAsset = new UUID((string)h["eyes_asset"]);
535 ShirtItem = new UUID((string)h["shirt_item"]);
536 ShirtAsset = new UUID((string)h["shirt_asset"]);
537 PantsItem = new UUID((string)h["pants_item"]);
538 PantsAsset = new UUID((string)h["pants_asset"]);
539 ShoesItem = new UUID((string)h["shoes_item"]);
540 ShoesAsset = new UUID((string)h["shoes_asset"]);
541 SocksItem = new UUID((string)h["socks_item"]);
542 SocksAsset = new UUID((string)h["socks_asset"]);
543 JacketItem = new UUID((string)h["jacket_item"]);
544 JacketAsset = new UUID((string)h["jacket_asset"]);
545 GlovesItem = new UUID((string)h["gloves_item"]);
546 GlovesAsset = new UUID((string)h["gloves_asset"]);
547 UnderShirtItem = new UUID((string)h["undershirt_item"]);
548 UnderShirtAsset = new UUID((string)h["undershirt_asset"]);
549 UnderPantsItem = new UUID((string)h["underpants_item"]);
550 UnderPantsAsset = new UUID((string)h["underpants_asset"]);
551 SkirtItem = new UUID((string)h["skirt_item"]);
552 SkirtAsset = new UUID((string)h["skirt_asset"]);
553
554 if (h.ContainsKey("attachments"))
555 { 318 {
556 SetAttachmentsString(h["attachments"].ToString()); 319 byte[] tbytes = appearance.Texture.GetBytes();
320 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
557 } 321 }
322
323 m_visualparams = null;
324 if (appearance.VisualParams != null)
325 m_visualparams = (byte[])appearance.VisualParams.Clone();
326
327 // Copy the attachment, force append mode since that ensures consistency
328 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
329 foreach (AvatarAttachment attachment in appearance.GetAttachments())
330 AppendAttachment(new AvatarAttachment(attachment));
331 }
332
333 protected virtual void SetDefaultWearables()
334 {
335 m_wearables = AvatarWearable.DefaultWearables;
558 } 336 }
559 337
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 338 protected virtual void SetDefaultParams()
561
562 public void SetAttachments(AttachmentData[] data)
563 { 339 {
564 foreach (AttachmentData a in data) 340 m_visualparams = new byte[VISUALPARAM_COUNT];
341 for (int i = 0; i < VISUALPARAM_COUNT; i++)
565 { 342 {
566 m_attachments[a.AttachPoint] = new UUID[2]; 343 m_visualparams[i] = 150;
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 } 344 }
570 } 345 }
571 346
572 public void SetAttachments(Hashtable data) 347 protected virtual void SetDefaultTexture()
573 { 348 {
574 m_attachments.Clear(); 349 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
575 350 // The initialization of these seems to force a rebake regardless of whether it is needed
576 if (data == null) 351 // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
577 return; 352 // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
353 // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
354 // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
355 // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
356 // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
357 // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
358 }
578 359
579 foreach (DictionaryEntry e in data) 360 /// <summary>
361 /// Set up appearance textures.
362 /// Returns boolean that indicates whether the new entries actually change the
363 /// existing values.
364 /// </summary>
365 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
366 {
367 if (textureEntry == null)
368 return false;
369
370 // There are much simpler versions of this copy that could be
371 // made. We determine if any of the textures actually
372 // changed to know if the appearance should be saved later
373 bool changed = false;
374 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
580 { 375 {
581 int attachpoint = Convert.ToInt32(e.Key); 376 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
582 377 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
583 if (m_attachments.ContainsKey(attachpoint)) 378
584 continue; 379 if (newface == null)
380 {
381 if (oldface == null) continue;
382 }
383 else
384 {
385 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
386 }
585 387
586 UUID item; 388 m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
587 UUID asset; 389 changed = true;
390// DEBUG ON
391 if (newface != null)
392 m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID);
393// DEBUG OFF
394 }
588 395
589 Hashtable uuids = (Hashtable) e.Value; 396 return changed;
590 UUID.TryParse(uuids["item"].ToString(), out item); 397 }
591 UUID.TryParse(uuids["asset"].ToString(), out asset); 398
399 /// <summary>
400 /// Set up visual parameters for the avatar and refresh the avatar height
401 /// Returns boolean that indicates whether the new entries actually change the
402 /// existing values.
403 /// </summary>
404 public virtual bool SetVisualParams(byte[] visualParams)
405 {
406 if (visualParams == null)
407 return false;
408
409 // There are much simpler versions of this copy that could be
410 // made. We determine if any of the visual parameters actually
411 // changed to know if the appearance should be saved later
412 bool changed = false;
413 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
414 {
415 if (visualParams[i] != m_visualparams[i])
416 {
417// DEBUG ON
418 m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
419 i,m_visualparams[i],visualParams[i]);
420// DEBUG OFF
421 m_visualparams[i] = visualParams[i];
422 changed = true;
423 }
424 }
592 425
593 UUID[] attachment = new UUID[2]; 426 // Reset the height if the visual parameters actually changed
594 attachment[0] = item; 427 if (changed)
595 attachment[1] = asset; 428 SetHeight();
596 429
597 m_attachments[attachpoint] = attachment; 430 return changed;
598 }
599 } 431 }
600 432
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 433 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
602 { 434 {
603 return m_attachments; 435 SetTextureEntries(textureEntry);
436 SetVisualParams(visualParams);
604 } 437 }
438
439 public virtual void SetHeight()
440 {
441 m_avatarHeight = 1.23077f // Shortest possible avatar height
442 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
443 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
444 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
445 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
446 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
447 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
605 448
606 public Hashtable GetAttachments() 449 m_hipOffset = (((1.23077f // Half of avatar
450 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
451 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
452 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
453 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
454 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
455 }
456
457 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
607 { 458 {
608 if (m_attachments.Count == 0) 459// DEBUG ON
609 return null; 460// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
461// DEBUG OFF
462 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
463 }
610 464
611 Hashtable ret = new Hashtable();
612 465
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 466// DEBUG ON
614 { 467 public override String ToString()
615 int attachpoint = kvp.Key; 468 {
616 UUID[] uuids = kvp.Value; 469 String s = "";
617 470
618 Hashtable data = new Hashtable(); 471 s += String.Format("Serial: {0}\n",m_serial);
619 data["item"] = uuids[0].ToString(); 472
620 data["asset"] = uuids[1].ToString(); 473 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
474 if (m_texture.FaceTextures[i] != null)
475 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
621 476
622 ret[attachpoint] = data; 477 foreach (AvatarWearable awear in m_wearables)
623 } 478 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
624 479
625 return ret; 480 s += "Visual Params: ";
481 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
482 s += String.Format("{0},",m_visualparams[j]);
483 s += "\n";
484
485 return s;
626 } 486 }
487// DEBUG OFF
627 488
628 public List<int> GetAttachedPoints() 489 /// <summary>
490 /// Get a list of the attachments, note that there may be
491 /// duplicate attachpoints
492 /// </summary>
493 public List<AvatarAttachment> GetAttachments()
629 { 494 {
630 return new List<int>(m_attachments.Keys); 495 List<AvatarAttachment> alist = new List<AvatarAttachment>();
496 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
497 {
498 foreach (AvatarAttachment attach in kvp.Value)
499 alist.Add(new AvatarAttachment(attach));
500 }
501
502 return alist;
631 } 503 }
632 504
633 public UUID GetAttachedItem(int attachpoint) 505 internal void AppendAttachment(AvatarAttachment attach)
634 { 506 {
635 if (!m_attachments.ContainsKey(attachpoint)) 507 if (! m_attachments.ContainsKey(attach.AttachPoint))
636 return UUID.Zero; 508 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
637 509 m_attachments[attach.AttachPoint].Add(attach);
638 return m_attachments[attachpoint][0];
639 } 510 }
640 511
641 public UUID GetAttachedAsset(int attachpoint) 512 internal void ReplaceAttachment(AvatarAttachment attach)
642 { 513 {
643 if (!m_attachments.ContainsKey(attachpoint)) 514 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
644 return UUID.Zero; 515 m_attachments[attach.AttachPoint].Add(attach);
645
646 return m_attachments[attachpoint][1];
647 } 516 }
648 517
518 /// <summary>
519 /// Add an attachment, if the attachpoint has the
520 /// 0x80 bit set then we assume this is an append
521 /// operation otherwise we replace whatever is
522 /// currently attached at the attachpoint
523 /// </summary>
649 public void SetAttachment(int attachpoint, UUID item, UUID asset) 524 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 { 525 {
651 if (attachpoint == 0) 526 if (attachpoint == 0)
@@ -658,31 +533,47 @@ namespace OpenSim.Framework
658 return; 533 return;
659 } 534 }
660 535
661 if (!m_attachments.ContainsKey(attachpoint)) 536 // check if this is an append or a replace, 0x80 marks it as an append
662 m_attachments[attachpoint] = new UUID[2]; 537 if ((attachpoint & 0x80) > 0)
663 538 {
664 m_attachments[attachpoint][0] = item; 539 // strip the append bit
665 m_attachments[attachpoint][1] = asset; 540 int point = attachpoint & 0x7F;
541 AppendAttachment(new AvatarAttachment(point, item, asset));
542 }
543 else
544 {
545 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
546 }
666 } 547 }
667 548
668 public int GetAttachpoint(UUID itemID) 549 public int GetAttachpoint(UUID itemID)
669 { 550 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 551 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
671 { 552 {
672 if (kvp.Value[0] == itemID) 553 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
673 { 554 if (index >= 0)
674 return kvp.Key; 555 return kvp.Key;
675 }
676 } 556 }
557
677 return 0; 558 return 0;
678 } 559 }
679 560
680 public void DetachAttachment(UUID itemID) 561 public void DetachAttachment(UUID itemID)
681 { 562 {
682 int attachpoint = GetAttachpoint(itemID); 563 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
564 {
565 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
566 if (index >= 0)
567 {
568 // Remove it from the list of attachments at that attach point
569 m_attachments[kvp.Key].RemoveAt(index);
683 570
684 if (attachpoint > 0) 571 // And remove the list if there are no more attachments here
685 m_attachments.Remove(attachpoint); 572 if (m_attachments[kvp.Key].Count == 0)
573 m_attachments.Remove(kvp.Key);
574 return;
575 }
576 }
686 } 577 }
687 578
688 public void ClearAttachments() 579 public void ClearAttachments()
@@ -690,42 +581,123 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 581 m_attachments.Clear();
691 } 582 }
692 583
693 string GetAttachmentsString() 584 /// <summary>
585 /// Create an OSDMap from the appearance data
586 /// </summary>
587 public OSDMap Pack()
694 { 588 {
695 List<string> strings = new List<string>(); 589 OSDMap data = new OSDMap();
696 590
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 591 data["serial"] = OSD.FromInteger(m_serial);
592 data["height"] = OSD.FromReal(m_avatarHeight);
593 data["hipoffset"] = OSD.FromReal(m_hipOffset);
594
595 // Wearables
596 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
597 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
598 wears.Add(m_wearables[i].Pack());
599 data["wearables"] = wears;
600
601 // Avatar Textures
602 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
603 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 604 {
699 strings.Add(e.Key.ToString()); 605 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 606 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 607 else
608 textures.Add(OSD.FromUUID(UUID.Zero));
702 } 609 }
610 data["textures"] = textures;
703 611
704 return String.Join(",", strings.ToArray()); 612 // Visual Parameters
613 OSDBinary visualparams = new OSDBinary(m_visualparams);
614 data["visualparams"] = visualparams;
615
616 // Attachments
617 OSDArray attachs = new OSDArray(m_attachments.Count);
618 foreach (AvatarAttachment attach in GetAttachments())
619 attachs.Add(attach.Pack());
620 data["attachments"] = attachs;
621
622 return data;
705 } 623 }
706 624
707 void SetAttachmentsString(string data) 625 /// <summary>
626 /// Unpack and OSDMap and initialize the appearance
627 /// from it
628 /// </summary>
629 public void Unpack(OSDMap data)
708 { 630 {
709 string[] strings = data.Split(new char[] {','}); 631 if ((data != null) && (data["serial"] != null))
710 int i = 0; 632 m_serial = data["serial"].AsInteger();
633 if ((data != null) && (data["height"] != null))
634 m_avatarHeight = (float)data["height"].AsReal();
635 if ((data != null) && (data["hipoffset"] != null))
636 m_hipOffset = (float)data["hipoffset"].AsReal();
637
638 try
639 {
640 // Wearables
641 SetDefaultWearables();
642 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
643 {
644 OSDArray wears = (OSDArray)(data["wearables"]);
645 for (int i = 0; i < wears.Count; i++)
646 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
647 }
648 else
649 {
650 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
651 }
711 652
712 m_attachments.Clear(); 653 // Avatar Textures
654 SetDefaultTexture();
655 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
656 {
657 OSDArray textures = (OSDArray)(data["textures"]);
658 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
659 {
660 if (textures[i] != null)
661 {
662 UUID textureID = textures[i].AsUUID();
663 if (textureID != UUID.Zero)
664 m_texture.CreateFace((uint)i).TextureID = textureID;
665 }
666 }
667 }
668 else
669 {
670 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
671 }
713 672
714 while (strings.Length - i > 2) 673 // Visual Parameters
715 { 674 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 675 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 676 {
718 UUID asset = new UUID(strings[i+2]); 677 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 678 m_visualparams = data["visualparams"].AsBinary();
679 }
680 else
681 {
682 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
683 }
720 684
721 if (!m_attachments.ContainsKey(attachpoint)) 685 // Attachments
686 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
687 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 688 {
723 m_attachments[attachpoint] = new UUID[2]; 689 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 690 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 691 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
726 } 692 }
727 } 693 }
694 catch (Exception e)
695 {
696 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
697 }
728 } 698 }
699
700
729 /// <summary> 701 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 702 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 703 /// Generated from LibOMV's Visual Params list
diff --git a/OpenSim/Framework/AvatarAttachment.cs b/OpenSim/Framework/AvatarAttachment.cs
new file mode 100644
index 0000000..c68d78d
--- /dev/null
+++ b/OpenSim/Framework/AvatarAttachment.cs
@@ -0,0 +1,78 @@
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
28using System;
29using OpenMetaverse;
30using OpenMetaverse.StructuredData;
31
32namespace OpenSim.Framework
33{
34 public class AvatarAttachment
35 {
36 public int AttachPoint;
37 public UUID ItemID;
38 public UUID AssetID;
39
40 public AvatarAttachment(AvatarAttachment attach)
41 {
42 AttachPoint = attach.AttachPoint;
43 ItemID = attach.ItemID;
44 AssetID = attach.AssetID;
45 }
46
47 public AvatarAttachment(int point, UUID item, UUID asset)
48 {
49 AttachPoint = point;
50 ItemID = item;
51 AssetID = asset;
52 }
53
54 public AvatarAttachment(OSDMap args)
55 {
56 Unpack(args);
57 }
58
59 public OSDMap Pack()
60 {
61 OSDMap attachdata = new OSDMap();
62 attachdata["point"] = OSD.FromInteger(AttachPoint);
63 attachdata["item"] = OSD.FromUUID(ItemID);
64 attachdata["asset"] = OSD.FromUUID(AssetID);
65
66 return attachdata;
67 }
68
69
70 public void Unpack(OSDMap args)
71 {
72 if (args["point"] != null)
73 AttachPoint = args["point"].AsInteger();
74 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
75 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
76 }
77 }
78}
diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs
index 30c5172..87098bf 100644
--- a/OpenSim/Framework/AvatarWearable.cs
+++ b/OpenSim/Framework/AvatarWearable.cs
@@ -26,14 +26,32 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Runtime.Serialization;
30using System.Security.Permissions;
31using OpenMetaverse; 29using OpenMetaverse;
30using OpenMetaverse.StructuredData;
32 31
33namespace OpenSim.Framework 32namespace OpenSim.Framework
34{ 33{
35 public class AvatarWearable 34 public class AvatarWearable
36 { 35 {
36 // these are guessed at by the list here -
37 // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll
38 // correct them over time for when were are wrong.
39 public static readonly int BODY = 0;
40 public static readonly int SKIN = 1;
41 public static readonly int HAIR = 2;
42 public static readonly int EYES = 3;
43 public static readonly int SHIRT = 4;
44 public static readonly int PANTS = 5;
45 public static readonly int SHOES = 6;
46 public static readonly int SOCKS = 7;
47 public static readonly int JACKET = 8;
48 public static readonly int GLOVES = 9;
49 public static readonly int UNDERSHIRT = 10;
50 public static readonly int UNDERPANTS = 11;
51 public static readonly int SKIRT = 12;
52
53 public static readonly int MAX_WEARABLES = 13;
54
37 public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); 55 public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
38 public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); 56 public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
39 57
@@ -62,12 +80,32 @@ namespace OpenSim.Framework
62 ItemID = itemId; 80 ItemID = itemId;
63 } 81 }
64 82
83 public AvatarWearable(OSDMap args)
84 {
85 Unpack(args);
86 }
87
88 public OSDMap Pack()
89 {
90 OSDMap weardata = new OSDMap();
91 weardata["item"] = OSD.FromUUID(ItemID);
92 weardata["asset"] = OSD.FromUUID(AssetID);
93
94 return weardata;
95 }
96
97 public void Unpack(OSDMap args)
98 {
99 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
100 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
101 }
102
65 public static AvatarWearable[] DefaultWearables 103 public static AvatarWearable[] DefaultWearables
66 { 104 {
67 get 105 get
68 { 106 {
69 AvatarWearable[] defaultWearables = new AvatarWearable[13]; //should be 13 of these 107 AvatarWearable[] defaultWearables = new AvatarWearable[MAX_WEARABLES]; //should be 13 of these
70 for (int i = 0; i < 13; i++) 108 for (int i = 0; i < MAX_WEARABLES; i++)
71 { 109 {
72 defaultWearables[i] = new AvatarWearable(); 110 defaultWearables[i] = new AvatarWearable();
73 } 111 }
diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs
index 72283de..872de9a 100644
--- a/OpenSim/Framework/Capabilities/Caps.cs
+++ b/OpenSim/Framework/Capabilities/Caps.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using System.IO; 31using System.IO;
32using System.Reflection; 32using System.Reflection;
33using log4net; 33using log4net;
34using Nini.Config;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenSim.Framework.Servers; 36using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer; 37using OpenSim.Framework.Servers.HttpServer;
@@ -112,6 +113,8 @@ namespace OpenSim.Framework.Capabilities
112 private string m_regionName; 113 private string m_regionName;
113 private object m_fetchLock = new Object(); 114 private object m_fetchLock = new Object();
114 115
116 private bool m_persistBakedTextures = false;
117
115 public bool SSLCaps 118 public bool SSLCaps
116 { 119 {
117 get { return m_httpListener.UseSSL; } 120 get { return m_httpListener.UseSSL; }
@@ -145,6 +148,15 @@ namespace OpenSim.Framework.Capabilities
145 148
146 m_httpListenPort = httpPort; 149 m_httpListenPort = httpPort;
147 150
151 m_persistBakedTextures = false;
152 IConfigSource config = m_Scene.Config;
153 if (config != null)
154 {
155 IConfig sconfig = config.Configs["Startup"];
156 if (sconfig != null)
157 m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures);
158 }
159
148 if (httpServer != null && httpServer.UseSSL) 160 if (httpServer != null && httpServer.UseSSL)
149 { 161 {
150 m_httpListenPort = httpServer.SSLPort; 162 m_httpListenPort = httpServer.SSLPort;
@@ -976,12 +988,14 @@ namespace OpenSim.Framework.Capabilities
976 988
977 public void BakedTextureUploaded(UUID assetID, byte[] data) 989 public void BakedTextureUploaded(UUID assetID, byte[] data)
978 { 990 {
979 m_log.DebugFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); 991// DEBUG ON
992 m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
993// DEBUG OFF
980 AssetBase asset; 994 AssetBase asset;
981 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); 995 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
982 asset.Data = data; 996 asset.Data = data;
983 asset.Temporary = true; 997 asset.Temporary = true;
984 asset.Local = true; 998 asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are
985 m_assetCache.Store(asset); 999 m_assetCache.Store(asset);
986 } 1000 }
987 1001
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 0dc5dbc..66487f7 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -28,6 +28,8 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenMetaverse.StructuredData; 34using OpenMetaverse.StructuredData;
33 35
@@ -225,46 +227,6 @@ namespace OpenSim.Framework
225 } 227 }
226 } 228 }
227 229
228 public class AttachmentData
229 {
230 public int AttachPoint;
231 public UUID ItemID;
232 public UUID AssetID;
233
234 public AttachmentData(int point, UUID item, UUID asset)
235 {
236 AttachPoint = point;
237 ItemID = item;
238 AssetID = asset;
239 }
240
241 public AttachmentData(OSDMap args)
242 {
243 UnpackUpdateMessage(args);
244 }
245
246 public OSDMap PackUpdateMessage()
247 {
248 OSDMap attachdata = new OSDMap();
249 attachdata["point"] = OSD.FromInteger(AttachPoint);
250 attachdata["item"] = OSD.FromUUID(ItemID);
251 attachdata["asset"] = OSD.FromUUID(AssetID);
252
253 return attachdata;
254 }
255
256
257 public void UnpackUpdateMessage(OSDMap args)
258 {
259 if (args["point"] != null)
260 AttachPoint = args["point"].AsInteger();
261 if (args["item"] != null)
262 ItemID = args["item"].AsUUID();
263 if (args["asset"] != null)
264 AssetID = args["asset"].AsUUID();
265 }
266 }
267
268 public class ControllerData 230 public class ControllerData
269 { 231 {
270 public UUID ItemID; 232 public UUID ItemID;
@@ -348,11 +310,20 @@ namespace OpenSim.Framework
348 public UUID GranterID; 310 public UUID GranterID;
349 311
350 // Appearance 312 // Appearance
313 public AvatarAppearance Appearance;
314
315// DEBUG ON
316 private static readonly ILog m_log =
317 LogManager.GetLogger(
318 MethodBase.GetCurrentMethod().DeclaringType);
319// DEBUG OFF
320
321/*
351 public byte[] AgentTextures; 322 public byte[] AgentTextures;
352 public byte[] VisualParams; 323 public byte[] VisualParams;
353 public UUID[] Wearables; 324 public UUID[] Wearables;
354 public AttachmentData[] Attachments; 325 public AvatarAttachment[] Attachments;
355 326*/
356 // Scripted 327 // Scripted
357 public ControllerData[] Controllers; 328 public ControllerData[] Controllers;
358 329
@@ -360,6 +331,10 @@ namespace OpenSim.Framework
360 331
361 public virtual OSDMap Pack() 332 public virtual OSDMap Pack()
362 { 333 {
334// DEBUG ON
335 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data");
336// DEBUG OFF
337
363 OSDMap args = new OSDMap(); 338 OSDMap args = new OSDMap();
364 args["message_type"] = OSD.FromString("AgentData"); 339 args["message_type"] = OSD.FromString("AgentData");
365 340
@@ -413,6 +388,9 @@ namespace OpenSim.Framework
413 args["animations"] = anims; 388 args["animations"] = anims;
414 } 389 }
415 390
391 if (Appearance != null)
392 args["packed_appearance"] = Appearance.Pack();
393
416 //if ((AgentTextures != null) && (AgentTextures.Length > 0)) 394 //if ((AgentTextures != null) && (AgentTextures.Length > 0))
417 //{ 395 //{
418 // OSDArray textures = new OSDArray(AgentTextures.Length); 396 // OSDArray textures = new OSDArray(AgentTextures.Length);
@@ -421,30 +399,39 @@ namespace OpenSim.Framework
421 // args["agent_textures"] = textures; 399 // args["agent_textures"] = textures;
422 //} 400 //}
423 401
424 402 // The code to pack textures, visuals, wearables and attachments
425 if ((AgentTextures != null) && (AgentTextures.Length > 0)) 403 // should be removed; packed appearance contains the full appearance
426 args["texture_entry"] = OSD.FromBinary(AgentTextures); 404 // This is retained for backward compatibility only
405 if (Appearance.Texture != null)
406 {
407 byte[] rawtextures = Appearance.Texture.GetBytes();
408 args["texture_entry"] = OSD.FromBinary(rawtextures);
409 }
427 410
428 if ((VisualParams != null) && (VisualParams.Length > 0)) 411 if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0))
429 args["visual_params"] = OSD.FromBinary(VisualParams); 412 args["visual_params"] = OSD.FromBinary(Appearance.VisualParams);
430 413
431 // We might not pass this in all cases... 414 // We might not pass this in all cases...
432 if ((Wearables != null) && (Wearables.Length > 0)) 415 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
433 { 416 {
434 OSDArray wears = new OSDArray(Wearables.Length); 417 OSDArray wears = new OSDArray(Appearance.Wearables.Length * 2);
435 foreach (UUID uuid in Wearables) 418 foreach (AvatarWearable awear in Appearance.Wearables)
436 wears.Add(OSD.FromUUID(uuid)); 419 {
420 wears.Add(OSD.FromUUID(awear.ItemID));
421 wears.Add(OSD.FromUUID(awear.AssetID));
422 }
437 args["wearables"] = wears; 423 args["wearables"] = wears;
438 } 424 }
439 425
440 426 List<AvatarAttachment> attachments = Appearance.GetAttachments();
441 if ((Attachments != null) && (Attachments.Length > 0)) 427 if ((attachments != null) && (attachments.Count > 0))
442 { 428 {
443 OSDArray attachs = new OSDArray(Attachments.Length); 429 OSDArray attachs = new OSDArray(attachments.Count);
444 foreach (AttachmentData att in Attachments) 430 foreach (AvatarAttachment att in attachments)
445 attachs.Add(att.PackUpdateMessage()); 431 attachs.Add(att.Pack());
446 args["attachments"] = attachs; 432 args["attachments"] = attachs;
447 } 433 }
434 // End of code to remove
448 435
449 if ((Controllers != null) && (Controllers.Length > 0)) 436 if ((Controllers != null) && (Controllers.Length > 0))
450 { 437 {
@@ -469,6 +456,10 @@ namespace OpenSim.Framework
469 /// <param name="hash"></param> 456 /// <param name="hash"></param>
470 public virtual void Unpack(OSDMap args) 457 public virtual void Unpack(OSDMap args)
471 { 458 {
459// DEBUG ON
460 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data");
461// DEBUG OFF
462
472 if (args.ContainsKey("region_id")) 463 if (args.ContainsKey("region_id"))
473 UUID.TryParse(args["region_id"].AsString(), out RegionID); 464 UUID.TryParse(args["region_id"].AsString(), out RegionID);
474 465
@@ -581,34 +572,53 @@ namespace OpenSim.Framework
581 // AgentTextures[i++] = o.AsUUID(); 572 // AgentTextures[i++] = o.AsUUID();
582 //} 573 //}
583 574
575 Appearance = new AvatarAppearance(AgentID);
576
577 // The code to unpack textures, visuals, wearables and attachments
578 // should be removed; packed appearance contains the full appearance
579 // This is retained for backward compatibility only
584 if (args["texture_entry"] != null) 580 if (args["texture_entry"] != null)
585 AgentTextures = args["texture_entry"].AsBinary(); 581 {
582 byte[] rawtextures = args["texture_entry"].AsBinary();
583 Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
584 Appearance.SetTextureEntries(textures);
585 }
586 586
587 if (args["visual_params"] != null) 587 if (args["visual_params"] != null)
588 VisualParams = args["visual_params"].AsBinary(); 588 Appearance.SetVisualParams(args["visual_params"].AsBinary());
589 589
590 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) 590 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
591 { 591 {
592 OSDArray wears = (OSDArray)(args["wearables"]); 592 OSDArray wears = (OSDArray)(args["wearables"]);
593 Wearables = new UUID[wears.Count]; 593 for (int i = 0; i < wears.Count / 2; i++)
594 int i = 0; 594 {
595 foreach (OSD o in wears) 595 AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
596 Wearables[i++] = o.AsUUID(); 596 Appearance.SetWearable(i,awear);
597 }
597 } 598 }
598 599
599 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) 600 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
600 { 601 {
601 OSDArray attachs = (OSDArray)(args["attachments"]); 602 OSDArray attachs = (OSDArray)(args["attachments"]);
602 Attachments = new AttachmentData[attachs.Count];
603 int i = 0;
604 foreach (OSD o in attachs) 603 foreach (OSD o in attachs)
605 { 604 {
606 if (o.Type == OSDType.Map) 605 if (o.Type == OSDType.Map)
607 { 606 {
608 Attachments[i++] = new AttachmentData((OSDMap)o); 607 // We know all of these must end up as attachments so we
608 // append rather than replace to ensure multiple attachments
609 // per point continues to work
610 Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
609 } 611 }
610 } 612 }
611 } 613 }
614 // end of code to remove
615
616 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
617 Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
618// DEBUG ON
619 else
620 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
621// DEBUG OFF
612 622
613 if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) 623 if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
614 { 624 {
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 94815cd..027f9c5 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Framework
43 43
44 public delegate void TextureRequest(Object sender, TextureRequestArgs e); 44 public delegate void TextureRequest(Object sender, TextureRequestArgs e);
45 45
46 public delegate void AvatarNowWearing(Object sender, AvatarWearingArgs e); 46 public delegate void AvatarNowWearing(IClientAPI sender, AvatarWearingArgs e);
47 47
48 public delegate void ImprovedInstantMessage(IClientAPI remoteclient, GridInstantMessage im); 48 public delegate void ImprovedInstantMessage(IClientAPI remoteclient, GridInstantMessage im);
49 49
@@ -65,7 +65,7 @@ namespace OpenSim.Framework
65 65
66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); 66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
67 67
68 public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams); 68 public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams);
69 69
70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID); 70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
71 71
@@ -711,7 +711,7 @@ namespace OpenSim.Framework
711 event TeleportLandmarkRequest OnTeleportLandmarkRequest; 711 event TeleportLandmarkRequest OnTeleportLandmarkRequest;
712 event DeRezObject OnDeRezObject; 712 event DeRezObject OnDeRezObject;
713 event Action<IClientAPI> OnRegionHandShakeReply; 713 event Action<IClientAPI> OnRegionHandShakeReply;
714 event GenericCall2 OnRequestWearables; 714 event GenericCall1 OnRequestWearables;
715 event GenericCall1 OnCompleteMovementToRegion; 715 event GenericCall1 OnCompleteMovementToRegion;
716 event UpdateAgent OnPreAgentUpdate; 716 event UpdateAgent OnPreAgentUpdate;
717 event UpdateAgent OnAgentUpdate; 717 event UpdateAgent OnAgentUpdate;
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
index 2fda6f3..05d8469 100644
--- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
+++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
@@ -65,9 +65,7 @@ namespace OpenSim.Framework.Tests
65 SessionId = UUID.Random(); 65 SessionId = UUID.Random();
66 66
67 AvAppearance = new AvatarAppearance(AgentId); 67 AvAppearance = new AvatarAppearance(AgentId);
68 AvAppearance.SetDefaultWearables();
69 VisualParams = new byte[218]; 68 VisualParams = new byte[218];
70 AvAppearance.SetDefaultParams(VisualParams);
71 69
72 //body 70 //body
73 VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEIGHT] = 155; 71 VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEIGHT] = 155;