aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs63
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs987
-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, 793 insertions, 547 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..a4bb765 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,59 +26,139 @@
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{
38 // A special dictionary for avatar appearance
39 public struct LayerItem
40 {
41 public UUID ItemID;
42 public UUID AssetID;
43
44 public LayerItem(UUID itemID, UUID assetID)
45 {
46 ItemID = itemID;
47 AssetID = assetID;
48 }
49 }
50
51 public class Layer
52 {
53 protected int m_layerType;
54 protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>();
55 protected List<UUID> m_ids = new List<UUID>();
56
57 public Layer(int type)
58 {
59 m_layerType = type;
60 }
61
62 public int LayerType
63 {
64 get { return m_layerType; }
65 }
66
67 public int Count
68 {
69 get { return m_ids.Count; }
70 }
71
72 public void Add(UUID itemID, UUID assetID)
73 {
74 if (m_items.ContainsKey(itemID))
75 return;
76 if (m_ids.Count >= 5)
77 return;
78
79 m_ids.Add(itemID);
80 m_items[itemID] = assetID;
81 }
82
83 public void Wear(UUID itemID, UUID assetID)
84 {
85 Clear();
86 Add(itemID, assetID);
87 }
88
89 public void Clear()
90 {
91 m_ids.Clear();
92 m_items.Clear();
93 }
94
95 public void RemoveItem(UUID itemID)
96 {
97 if (m_items.ContainsKey(itemID))
98 {
99 m_ids.Remove(itemID);
100 m_items.Remove(itemID);
101 }
102 }
103
104 public void RemoveAsset(UUID assetID)
105 {
106 UUID itemID = UUID.Zero;
107
108 foreach (KeyValuePair<UUID, UUID> kvp in m_items)
109 {
110 if (kvp.Value == assetID)
111 {
112 itemID = kvp.Key;
113 break;
114 }
115 }
116
117 if (itemID != UUID.Zero)
118 {
119 m_ids.Remove(itemID);
120 m_items.Remove(itemID);
121 }
122 }
123
124 public LayerItem this [int idx]
125 {
126 get
127 {
128 if (idx >= m_ids.Count || idx < 0)
129 return new LayerItem(UUID.Zero, UUID.Zero);
130
131 return new LayerItem(m_ids[idx], m_items[m_ids[idx]]);
132 }
133 }
134 }
135
35 /// <summary> 136 /// <summary>
36 /// Contains the Avatar's Appearance and methods to manipulate the appearance. 137 /// Contains the Avatar's Appearance and methods to manipulate the appearance.
37 /// </summary> 138 /// </summary>
38 public class AvatarAppearance 139 public class AvatarAppearance
39 { 140 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 141 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 142
72 public readonly static int VISUALPARAM_COUNT = 218; 143 public readonly static int VISUALPARAM_COUNT = 218;
73 144
145 public readonly static int TEXTURE_COUNT = 21;
146 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
147
74 protected UUID m_owner; 148 protected UUID m_owner;
149 protected int m_serial = 1;
150 protected byte[] m_visualparams;
151 protected Primitive.TextureEntry m_texture;
152 protected AvatarWearable[] m_wearables;
153 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
154 protected float m_avatarHeight = 0;
155 protected float m_hipOffset = 0;
75 156
76 public virtual UUID Owner 157 public virtual UUID Owner
77 { 158 {
78 get { return m_owner; } 159 get { return m_owner; }
79 set { m_owner = value; } 160 set { m_owner = value; }
80 } 161 }
81 protected int m_serial = 1;
82 162
83 public virtual int Serial 163 public virtual int Serial
84 { 164 {
@@ -86,15 +166,17 @@ namespace OpenSim.Framework
86 set { m_serial = value; } 166 set { m_serial = value; }
87 } 167 }
88 168
89 protected byte[] m_visualparams;
90
91 public virtual byte[] VisualParams 169 public virtual byte[] VisualParams
92 { 170 {
93 get { return m_visualparams; } 171 get { return m_visualparams; }
94 set { m_visualparams = value; } 172 set { m_visualparams = value; }
95 } 173 }
96 174
97 protected AvatarWearable[] m_wearables; 175 public virtual Primitive.TextureEntry Texture
176 {
177 get { return m_texture; }
178 set { m_texture = value; }
179 }
98 180
99 public virtual AvatarWearable[] Wearables 181 public virtual AvatarWearable[] Wearables
100 { 182 {
@@ -103,178 +185,135 @@ namespace OpenSim.Framework
103 } 185 }
104 186
105 public virtual UUID BodyItem { 187 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 188 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 189 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 190 }
109 191
110 public virtual UUID BodyAsset { 192 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 193 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 194 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 195 }
114 196
115 public virtual UUID SkinItem { 197 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 198 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 199 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 200 }
119 201
120 public virtual UUID SkinAsset { 202 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 203 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 204 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 205 }
124 206
125 public virtual UUID HairItem { 207 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 208 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 209 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 210 }
129 211
130 public virtual UUID HairAsset { 212 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 213 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 214 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 215 }
134 216
135 public virtual UUID EyesItem { 217 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 218 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 219 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 220 }
139 221
140 public virtual UUID EyesAsset { 222 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 223 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 224 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 225 }
144 226
145 public virtual UUID ShirtItem { 227 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 228 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 229 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 230 }
149 231
150 public virtual UUID ShirtAsset { 232 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 233 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 234 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 235 }
154 236
155 public virtual UUID PantsItem { 237 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 238 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 239 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 240 }
159 241
160 public virtual UUID PantsAsset { 242 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 243 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 244 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 245 }
164 246
165 public virtual UUID ShoesItem { 247 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 248 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 249 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 250 }
169 251
170 public virtual UUID ShoesAsset { 252 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 253 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 254 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 255 }
174 256
175 public virtual UUID SocksItem { 257 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 258 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 259 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 260 }
179 261
180 public virtual UUID SocksAsset { 262 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 263 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 264 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 265 }
184 266
185 public virtual UUID JacketItem { 267 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 268 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 269 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 270 }
189 271
190 public virtual UUID JacketAsset { 272 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 273 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 274 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 275 }
194 276
195 public virtual UUID GlovesItem { 277 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 278 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 279 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 280 }
199 281
200 public virtual UUID GlovesAsset { 282 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 283 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 284 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 285 }
204 286
205 public virtual UUID UnderShirtItem { 287 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 288 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 289 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 290 }
209 291
210 public virtual UUID UnderShirtAsset { 292 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 293 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 294 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 295 }
214 296
215 public virtual UUID UnderPantsItem { 297 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 298 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 299 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 300 }
219 301
220 public virtual UUID UnderPantsAsset { 302 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 303 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 304 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 305 }
224 306
225 public virtual UUID SkirtItem { 307 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 308 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 309 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 310 }
229 311
230 public virtual UUID SkirtAsset { 312 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 313 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 314 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 } 315 }
234 316
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 }
274
275 protected float m_avatarHeight = 0;
276 protected float m_hipOffset = 0;
277
278 public virtual float AvatarHeight 317 public virtual float AvatarHeight
279 { 318 {
280 get { return m_avatarHeight; } 319 get { return m_avatarHeight; }
@@ -286,366 +325,295 @@ namespace OpenSim.Framework
286 get { return m_hipOffset; } 325 get { return m_hipOffset; }
287 } 326 }
288 327
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) {} 328 public AvatarAppearance() : this(UUID.Zero) {}
348 329
349 public AvatarAppearance(UUID owner) 330 public AvatarAppearance(UUID owner)
350 { 331 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 332// DEBUG ON
352 for (int i = 0; i < MAX_WEARABLES; i++) 333 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
353 { 334// DEBUG OFF
354 // this makes them all null 335 m_serial = 1;
355 m_wearables[i] = new AvatarWearable();
356 }
357 m_serial = 0;
358 m_owner = owner; 336 m_owner = owner;
359 //BuildVisualParamEnum() 337
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(); 338 SetDefaultWearables();
364 m_texture = GetDefaultTexture(); 339 SetDefaultTexture();
340 SetDefaultParams();
341 SetHeight();
342
343 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
365 } 344 }
366 345
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 346 public AvatarAppearance(UUID avatarID, OSDMap map)
368 { 347 {
348// DEBUG ON
349 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
350// DEBUG OFF
369 m_owner = avatarID; 351 m_owner = avatarID;
370 m_serial = 1; 352 Unpack(map);
371 m_wearables = wearables; 353 SetHeight();
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 354 }
375 355
376 /// <summary> 356 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 { 357 {
358// DEBUG ON
359 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
360// DEBUG OFF
361 m_serial = 1;
362 m_owner = avatarID;
363
364 if (wearables != null)
365 m_wearables = wearables;
366 else
367 SetDefaultWearables();
368
381 if (textureEntry != null) 369 if (textureEntry != null)
382 m_texture = textureEntry; 370 m_texture = textureEntry;
371 else
372 SetDefaultTexture();
373
383 if (visualParams != null) 374 if (visualParams != null)
384 m_visualparams = visualParams; 375 m_visualparams = visualParams;
376 else
377 SetDefaultParams();
385 378
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 379 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 380
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable) 381 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
417 {
418 m_wearables[wearableId] = wearable;
419 } 382 }
420 383
421 public static Primitive.TextureEntry GetDefaultTexture() 384 public AvatarAppearance(AvatarAppearance appearance)
422 { 385 {
423 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); 386// DEBUG ON
424 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); 387 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
425 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; 388// DEBUG OFF
426 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; 389 if (appearance == null)
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 }
433
434 public static byte[] GetDefaultVisualParams()
435 {
436 byte[] visualParams;
437 visualParams = new byte[VISUALPARAM_COUNT];
438 for (int i = 0; i < VISUALPARAM_COUNT; i++)
439 { 390 {
440 visualParams[i] = 100; 391 m_serial = 1;
441 } 392 m_owner = UUID.Zero;
442 return visualParams;
443 }
444 393
445 public override String ToString() 394 SetDefaultWearables();
446 { 395 SetDefaultTexture();
447 String s = "[Wearables] =>"; 396 SetDefaultParams();
448 s += " Body Item: " + BodyItem.ToString() + ";"; 397 SetHeight();
449 s += " Skin Item: " + SkinItem.ToString() + ";";
450 s += " Shirt Item: " + ShirtItem.ToString() + ";";
451 s += " Pants Item: " + PantsItem.ToString() + ";";
452 return s;
453 }
454 398
455 // this is used for OGS1 399 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 400
504 if (h.Contains("texture")) 401 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 } 402 }
516
517 403
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 404 m_serial = appearance.Serial;
405 m_owner = appearance.Owner;
519 406
520 m_wearables = new AvatarWearable[MAX_WEARABLES]; 407 m_wearables = null;
521 for (int i = 0; i < MAX_WEARABLES; i++) 408 if (appearance.Wearables != null)
522 { 409 {
523 // this makes them all null 410 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
524 m_wearables[i] = new AvatarWearable(); 411 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
412 SetWearable(i,appearance.Wearables[i]);
525 } 413 }
526 414
527 BodyItem = new UUID((string)h["body_item"]); 415 m_texture = null;
528 BodyAsset = new UUID((string)h["body_asset"]); 416 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 { 417 {
556 SetAttachmentsString(h["attachments"].ToString()); 418 byte[] tbytes = appearance.Texture.GetBytes();
419 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
557 } 420 }
421
422 m_visualparams = null;
423 if (appearance.VisualParams != null)
424 m_visualparams = (byte[])appearance.VisualParams.Clone();
425
426 // Copy the attachment, force append mode since that ensures consistency
427 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
428 foreach (AvatarAttachment attachment in appearance.GetAttachments())
429 AppendAttachment(new AvatarAttachment(attachment));
430 }
431
432 protected virtual void SetDefaultWearables()
433 {
434 m_wearables = AvatarWearable.DefaultWearables;
558 } 435 }
559 436
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 437 protected virtual void SetDefaultParams()
561
562 public void SetAttachments(AttachmentData[] data)
563 { 438 {
564 foreach (AttachmentData a in data) 439 m_visualparams = new byte[VISUALPARAM_COUNT];
440 for (int i = 0; i < VISUALPARAM_COUNT; i++)
565 { 441 {
566 m_attachments[a.AttachPoint] = new UUID[2]; 442 m_visualparams[i] = 150;
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 } 443 }
570 } 444 }
571 445
572 public void SetAttachments(Hashtable data) 446 protected virtual void SetDefaultTexture()
573 { 447 {
574 m_attachments.Clear(); 448 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
575 449 for (uint i = 0; i < TEXTURE_COUNT; i++)
576 if (data == null) 450 m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
577 return; 451 }
578 452
579 foreach (DictionaryEntry e in data) 453 /// <summary>
454 /// Set up appearance textures.
455 /// Returns boolean that indicates whether the new entries actually change the
456 /// existing values.
457 /// </summary>
458 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
459 {
460 if (textureEntry == null)
461 return false;
462
463 // There are much simpler versions of this copy that could be
464 // made. We determine if any of the textures actually
465 // changed to know if the appearance should be saved later
466 bool changed = false;
467 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
580 { 468 {
581 int attachpoint = Convert.ToInt32(e.Key); 469 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
582 470 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
583 if (m_attachments.ContainsKey(attachpoint)) 471
584 continue; 472 if (newface == null)
473 {
474 if (oldface == null) continue;
475 }
476 else
477 {
478 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
479 }
585 480
586 UUID item; 481 changed = true;
587 UUID asset; 482// DEBUG ON
483 if (newface != null)
484 m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID);
485// DEBUG OFF
486 }
588 487
589 Hashtable uuids = (Hashtable) e.Value; 488 m_texture = textureEntry;
590 UUID.TryParse(uuids["item"].ToString(), out item); 489 return changed;
591 UUID.TryParse(uuids["asset"].ToString(), out asset); 490 }
491
492 /// <summary>
493 /// Set up visual parameters for the avatar and refresh the avatar height
494 /// Returns boolean that indicates whether the new entries actually change the
495 /// existing values.
496 /// </summary>
497 public virtual bool SetVisualParams(byte[] visualParams)
498 {
499 if (visualParams == null)
500 return false;
501
502 // There are much simpler versions of this copy that could be
503 // made. We determine if any of the visual parameters actually
504 // changed to know if the appearance should be saved later
505 bool changed = false;
506 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
507 {
508 if (visualParams[i] != m_visualparams[i])
509 {
510// DEBUG ON
511// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
512// i,m_visualparams[i],visualParams[i]);
513// DEBUG OFF
514 m_visualparams[i] = visualParams[i];
515 changed = true;
516 }
517 }
592 518
593 UUID[] attachment = new UUID[2]; 519 // Reset the height if the visual parameters actually changed
594 attachment[0] = item; 520 if (changed)
595 attachment[1] = asset; 521 SetHeight();
596 522
597 m_attachments[attachpoint] = attachment; 523 return changed;
598 }
599 } 524 }
600 525
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 526 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
602 { 527 {
603 return m_attachments; 528 SetTextureEntries(textureEntry);
529 SetVisualParams(visualParams);
604 } 530 }
531
532 public virtual void SetHeight()
533 {
534 m_avatarHeight = 1.23077f // Shortest possible avatar height
535 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
536 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
537 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
538 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
539 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
540 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
605 541
606 public Hashtable GetAttachments() 542 m_hipOffset = (((1.23077f // Half of avatar
543 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
544 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
545 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
546 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
547 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
548 }
549
550 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
607 { 551 {
608 if (m_attachments.Count == 0) 552// DEBUG ON
609 return null; 553// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
554// DEBUG OFF
555 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
556 }
610 557
611 Hashtable ret = new Hashtable();
612 558
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 559// DEBUG ON
614 { 560 public override String ToString()
615 int attachpoint = kvp.Key; 561 {
616 UUID[] uuids = kvp.Value; 562 String s = "";
617 563
618 Hashtable data = new Hashtable(); 564 s += String.Format("Serial: {0}\n",m_serial);
619 data["item"] = uuids[0].ToString(); 565
620 data["asset"] = uuids[1].ToString(); 566 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
567 if (m_texture.FaceTextures[i] != null)
568 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
621 569
622 ret[attachpoint] = data; 570 foreach (AvatarWearable awear in m_wearables)
623 } 571 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
624 572
625 return ret; 573 s += "Visual Params: ";
574 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
575 s += String.Format("{0},",m_visualparams[j]);
576 s += "\n";
577
578 return s;
626 } 579 }
580// DEBUG OFF
627 581
628 public List<int> GetAttachedPoints() 582 /// <summary>
583 /// Get a list of the attachments, note that there may be
584 /// duplicate attachpoints
585 /// </summary>
586 public List<AvatarAttachment> GetAttachments()
629 { 587 {
630 return new List<int>(m_attachments.Keys); 588 List<AvatarAttachment> alist = new List<AvatarAttachment>();
589 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
590 {
591 foreach (AvatarAttachment attach in kvp.Value)
592 alist.Add(new AvatarAttachment(attach));
593 }
594
595 return alist;
631 } 596 }
632 597
633 public UUID GetAttachedItem(int attachpoint) 598 internal void AppendAttachment(AvatarAttachment attach)
634 { 599 {
635 if (!m_attachments.ContainsKey(attachpoint)) 600 if (! m_attachments.ContainsKey(attach.AttachPoint))
636 return UUID.Zero; 601 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
637 602 m_attachments[attach.AttachPoint].Add(attach);
638 return m_attachments[attachpoint][0];
639 } 603 }
640 604
641 public UUID GetAttachedAsset(int attachpoint) 605 internal void ReplaceAttachment(AvatarAttachment attach)
642 { 606 {
643 if (!m_attachments.ContainsKey(attachpoint)) 607 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
644 return UUID.Zero; 608 m_attachments[attach.AttachPoint].Add(attach);
645
646 return m_attachments[attachpoint][1];
647 } 609 }
648 610
611 /// <summary>
612 /// Add an attachment, if the attachpoint has the
613 /// 0x80 bit set then we assume this is an append
614 /// operation otherwise we replace whatever is
615 /// currently attached at the attachpoint
616 /// </summary>
649 public void SetAttachment(int attachpoint, UUID item, UUID asset) 617 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 { 618 {
651 if (attachpoint == 0) 619 if (attachpoint == 0)
@@ -658,31 +626,47 @@ namespace OpenSim.Framework
658 return; 626 return;
659 } 627 }
660 628
661 if (!m_attachments.ContainsKey(attachpoint)) 629 // check if this is an append or a replace, 0x80 marks it as an append
662 m_attachments[attachpoint] = new UUID[2]; 630 if ((attachpoint & 0x80) > 0)
663 631 {
664 m_attachments[attachpoint][0] = item; 632 // strip the append bit
665 m_attachments[attachpoint][1] = asset; 633 int point = attachpoint & 0x7F;
634 AppendAttachment(new AvatarAttachment(point, item, asset));
635 }
636 else
637 {
638 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
639 }
666 } 640 }
667 641
668 public int GetAttachpoint(UUID itemID) 642 public int GetAttachpoint(UUID itemID)
669 { 643 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 644 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
671 { 645 {
672 if (kvp.Value[0] == itemID) 646 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
673 { 647 if (index >= 0)
674 return kvp.Key; 648 return kvp.Key;
675 }
676 } 649 }
650
677 return 0; 651 return 0;
678 } 652 }
679 653
680 public void DetachAttachment(UUID itemID) 654 public void DetachAttachment(UUID itemID)
681 { 655 {
682 int attachpoint = GetAttachpoint(itemID); 656 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
657 {
658 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
659 if (index >= 0)
660 {
661 // Remove it from the list of attachments at that attach point
662 m_attachments[kvp.Key].RemoveAt(index);
683 663
684 if (attachpoint > 0) 664 // And remove the list if there are no more attachments here
685 m_attachments.Remove(attachpoint); 665 if (m_attachments[kvp.Key].Count == 0)
666 m_attachments.Remove(kvp.Key);
667 return;
668 }
669 }
686 } 670 }
687 671
688 public void ClearAttachments() 672 public void ClearAttachments()
@@ -690,42 +674,126 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 674 m_attachments.Clear();
691 } 675 }
692 676
693 string GetAttachmentsString() 677 #region Packing Functions
678
679 /// <summary>
680 /// Create an OSDMap from the appearance data
681 /// </summary>
682 public OSDMap Pack()
694 { 683 {
695 List<string> strings = new List<string>(); 684 OSDMap data = new OSDMap();
696 685
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 686 data["serial"] = OSD.FromInteger(m_serial);
687 data["height"] = OSD.FromReal(m_avatarHeight);
688 data["hipoffset"] = OSD.FromReal(m_hipOffset);
689
690 // Wearables
691 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
693 wears.Add(m_wearables[i].Pack());
694 data["wearables"] = wears;
695
696 // Avatar Textures
697 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
698 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 699 {
699 strings.Add(e.Key.ToString()); 700 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 701 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 702 else
703 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
702 } 704 }
705 data["textures"] = textures;
706
707 // Visual Parameters
708 OSDBinary visualparams = new OSDBinary(m_visualparams);
709 data["visualparams"] = visualparams;
710
711 // Attachments
712 OSDArray attachs = new OSDArray(m_attachments.Count);
713 foreach (AvatarAttachment attach in GetAttachments())
714 attachs.Add(attach.Pack());
715 data["attachments"] = attachs;
703 716
704 return String.Join(",", strings.ToArray()); 717 return data;
705 } 718 }
706 719
707 void SetAttachmentsString(string data) 720 /// <summary>
721 /// Unpack and OSDMap and initialize the appearance
722 /// from it
723 /// </summary>
724 public void Unpack(OSDMap data)
708 { 725 {
709 string[] strings = data.Split(new char[] {','}); 726 if ((data != null) && (data["serial"] != null))
710 int i = 0; 727 m_serial = data["serial"].AsInteger();
728 if ((data != null) && (data["height"] != null))
729 m_avatarHeight = (float)data["height"].AsReal();
730 if ((data != null) && (data["hipoffset"] != null))
731 m_hipOffset = (float)data["hipoffset"].AsReal();
732
733 try
734 {
735 // Wearables
736 SetDefaultWearables();
737 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
738 {
739 OSDArray wears = (OSDArray)(data["wearables"]);
740 for (int i = 0; i < wears.Count; i++)
741 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
742 }
743 else
744 {
745 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
746 }
711 747
712 m_attachments.Clear(); 748 // Avatar Textures
749 SetDefaultTexture();
750 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
751 {
752 OSDArray textures = (OSDArray)(data["textures"]);
753 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
754 {
755 UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
756 if (textures[i] != null)
757 textureID = textures[i].AsUUID();
758 m_texture.CreateFace((uint)i).TextureID = new UUID(textureID);
759 }
760 }
761 else
762 {
763 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
764 }
713 765
714 while (strings.Length - i > 2) 766 // Visual Parameters
715 { 767 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 768 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 769 {
718 UUID asset = new UUID(strings[i+2]); 770 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 771 m_visualparams = data["visualparams"].AsBinary();
772 }
773 else
774 {
775 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
776 }
720 777
721 if (!m_attachments.ContainsKey(attachpoint)) 778 // Attachments
779 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
780 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 781 {
723 m_attachments[attachpoint] = new UUID[2]; 782 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 783 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 784 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
726 } 785 }
727 } 786 }
787 catch (Exception e)
788 {
789 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
790 }
728 } 791 }
792
793 #endregion
794
795 #region VPElement
796
729 /// <summary> 797 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 798 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 799 /// Generated from LibOMV's Visual Params list
@@ -1488,5 +1556,6 @@ namespace OpenSim.Framework
1488 SKIRT_SKIRT_GREEN = 216, 1556 SKIRT_SKIRT_GREEN = 216,
1489 SKIRT_SKIRT_BLUE = 217 1557 SKIRT_SKIRT_BLUE = 217
1490 } 1558 }
1559 #endregion
1491 } 1560 }
1492} \ No newline at end of file 1561}
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;