aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/AvatarAppearance.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs794
1 files changed, 413 insertions, 381 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 829ad79..55646dd 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,163 +26,40 @@
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{
35 // A special dictionary for avatar appearance
36 public struct LayerItem
37 {
38 public UUID ItemID;
39 public UUID AssetID;
40
41 public LayerItem(UUID itemID, UUID assetID)
42 {
43 ItemID = itemID;
44 AssetID = assetID;
45 }
46 }
47
48 public class Layer
49 {
50 protected int m_layerType;
51 protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>();
52 protected List<UUID> m_ids = new List<UUID>();
53
54 public Layer(int type)
55 {
56 m_layerType = type;
57 }
58
59 public int LayerType
60 {
61 get { return m_layerType; }
62 }
63
64 public int Count
65 {
66 get { return m_ids.Count; }
67 }
68
69 public void Add(UUID itemID, UUID assetID)
70 {
71 if (m_items.ContainsKey(itemID))
72 return;
73 if (m_ids.Count >= 5)
74 return;
75
76 m_ids.Add(itemID);
77 m_items[itemID] = assetID;
78 }
79
80 public void Wear(UUID itemID, UUID assetID)
81 {
82 Clear();
83 Add(itemID, assetID);
84 }
85
86 public void Clear()
87 {
88 m_ids.Clear();
89 m_items.Clear();
90 }
91
92 public void RemoveItem(UUID itemID)
93 {
94 if (m_items.ContainsKey(itemID))
95 {
96 m_ids.Remove(itemID);
97 m_items.Remove(itemID);
98 }
99 }
100
101 public void RemoveAsset(UUID assetID)
102 {
103 UUID itemID = UUID.Zero;
104
105 foreach (KeyValuePair<UUID, UUID> kvp in m_items)
106 {
107 if (kvp.Value == assetID)
108 {
109 itemID = kvp.Key;
110 break;
111 }
112 }
113
114 if (itemID != UUID.Zero)
115 {
116 m_ids.Remove(itemID);
117 m_items.Remove(itemID);
118 }
119 }
120
121 public LayerItem this [int idx]
122 {
123 get
124 {
125 if (idx >= m_ids.Count || idx < 0)
126 return new LayerItem(UUID.Zero, UUID.Zero);
127
128 return new LayerItem(m_ids[idx], m_items[m_ids[idx]]);
129 }
130 }
131 }
132
133 public enum AppearanceLayer
134 {
135 BODY = 0,
136 SKIN = 1,
137 HAIR = 2,
138 EYES = 3,
139 SHIRT = 4,
140 PANTS = 5,
141 SHOES = 6,
142 SOCKS = 7,
143 JACKET = 8,
144 GLOVES = 9,
145 UNDERSHIRT = 10,
146 UNDERPANTS = 11,
147 SKIRT = 12,
148 ALPHA = 13,
149 TATTOO = 14,
150
151 MAX_WEARABLES = 15
152 }
153
154 /// <summary> 38 /// <summary>
155 /// Contains the Avatar's Appearance and methods to manipulate the appearance. 39 /// Contains the Avatar's Appearance and methods to manipulate the appearance.
156 /// </summary> 40 /// </summary>
157 public class AvatarAppearance 41 public class AvatarAppearance
158 { 42 {
159 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
160
161 private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
162 private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
163 private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
164 private static UUID SKIN_ITEM = new UUID("77c41e39-38f9-f75a-024e-585989bfabc9");
165 private static UUID SHIRT_ASSET = new UUID("00000000-38f9-1111-024e-222222111110");
166 private static UUID SHIRT_ITEM = new UUID("77c41e39-38f9-f75a-0000-585989bf0000");
167 private static UUID PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120");
168 private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111");
169 private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
170 private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66");
171 private static UUID ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594");
172 private static UUID TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007");
173 private static UUID ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8");
174 private static UUID TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1");
175 44
176 public readonly static int VISUALPARAM_COUNT = 218; 45 public readonly static int VISUALPARAM_COUNT = 218;
177 46
47 public readonly static int TEXTURE_COUNT = 21;
48
178 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, AvatarAttachment> m_attachments;
55 protected float m_avatarHeight = 0;
56 protected float m_hipOffset = 0;
179 57
180 public virtual UUID Owner 58 public virtual UUID Owner
181 { 59 {
182 get { return m_owner; } 60 get { return m_owner; }
183 set { m_owner = value; } 61 set { m_owner = value; }
184 } 62 }
185 protected int m_serial = 1;
186 63
187 public virtual int Serial 64 public virtual int Serial
188 { 65 {
@@ -190,15 +67,17 @@ namespace OpenSim.Framework
190 set { m_serial = value; } 67 set { m_serial = value; }
191 } 68 }
192 69
193 protected byte[] m_visualparams;
194
195 public virtual byte[] VisualParams 70 public virtual byte[] VisualParams
196 { 71 {
197 get { return m_visualparams; } 72 get { return m_visualparams; }
198 set { m_visualparams = value; } 73 set { m_visualparams = value; }
199 } 74 }
200 75
201 protected AvatarWearable[] m_wearables; 76 public virtual Primitive.TextureEntry Texture
77 {
78 get { return m_texture; }
79 set { m_texture = value; }
80 }
202 81
203 public virtual AvatarWearable[] Wearables 82 public virtual AvatarWearable[] Wearables
204 { 83 {
@@ -206,183 +85,141 @@ namespace OpenSim.Framework
206 set { m_wearables = value; } 85 set { m_wearables = value; }
207 } 86 }
208 87
88 public virtual Dictionary<int, AvatarAttachment> Attachments
89 {
90 get { return m_attachments; }
91 }
92
209 public virtual UUID BodyItem { 93 public virtual UUID BodyItem {
210 get { return m_wearables[(int)AppearanceLayer.BODY].ItemID; } 94 get { return m_wearables[AvatarWearable.BODY].ItemID; }
211 set { m_wearables[(int)AppearanceLayer.BODY].ItemID = value; } 95 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
212 } 96 }
213 97
214 public virtual UUID BodyAsset { 98 public virtual UUID BodyAsset {
215 get { return m_wearables[(int)AppearanceLayer.BODY].AssetID; } 99 get { return m_wearables[AvatarWearable.BODY].AssetID; }
216 set { m_wearables[(int)AppearanceLayer.BODY].AssetID = value; } 100 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
217 } 101 }
218 102
219 public virtual UUID SkinItem { 103 public virtual UUID SkinItem {
220 get { return m_wearables[(int)AppearanceLayer.SKIN].ItemID; } 104 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
221 set { m_wearables[(int)AppearanceLayer.SKIN].ItemID = value; } 105 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
222 } 106 }
223 107
224 public virtual UUID SkinAsset { 108 public virtual UUID SkinAsset {
225 get { return m_wearables[(int)AppearanceLayer.SKIN].AssetID; } 109 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
226 set { m_wearables[(int)AppearanceLayer.SKIN].AssetID = value; } 110 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
227 } 111 }
228 112
229 public virtual UUID HairItem { 113 public virtual UUID HairItem {
230 get { return m_wearables[(int)AppearanceLayer.HAIR].ItemID; } 114 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
231 set { m_wearables[(int)AppearanceLayer.HAIR].ItemID = value; } 115 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
232 } 116 }
233 117
234 public virtual UUID HairAsset { 118 public virtual UUID HairAsset {
235 get { return m_wearables[(int)AppearanceLayer.HAIR].AssetID; } 119 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
236 set { m_wearables[(int)AppearanceLayer.HAIR].AssetID = value; } 120 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
237 } 121 }
238 122
239 public virtual UUID EyesItem { 123 public virtual UUID EyesItem {
240 get { return m_wearables[(int)AppearanceLayer.EYES].ItemID; } 124 get { return m_wearables[AvatarWearable.EYES].ItemID; }
241 set { m_wearables[(int)AppearanceLayer.EYES].ItemID = value; } 125 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
242 } 126 }
243 127
244 public virtual UUID EyesAsset { 128 public virtual UUID EyesAsset {
245 get { return m_wearables[(int)AppearanceLayer.EYES].AssetID; } 129 get { return m_wearables[AvatarWearable.EYES].AssetID; }
246 set { m_wearables[(int)AppearanceLayer.EYES].AssetID = value; } 130 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
247 } 131 }
248 132
249 public virtual UUID ShirtItem { 133 public virtual UUID ShirtItem {
250 get { return m_wearables[(int)AppearanceLayer.SHIRT].ItemID; } 134 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
251 set { m_wearables[(int)AppearanceLayer.SHIRT].ItemID = value; } 135 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
252 } 136 }
253 137
254 public virtual UUID ShirtAsset { 138 public virtual UUID ShirtAsset {
255 get { return m_wearables[(int)AppearanceLayer.SHIRT].AssetID; } 139 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
256 set { m_wearables[(int)AppearanceLayer.SHIRT].AssetID = value; } 140 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
257 } 141 }
258 142
259 public virtual UUID PantsItem { 143 public virtual UUID PantsItem {
260 get { return m_wearables[(int)AppearanceLayer.PANTS].ItemID; } 144 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
261 set { m_wearables[(int)AppearanceLayer.PANTS].ItemID = value; } 145 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
262 } 146 }
263 147
264 public virtual UUID PantsAsset { 148 public virtual UUID PantsAsset {
265 get { return m_wearables[(int)AppearanceLayer.PANTS].AssetID; } 149 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
266 set { m_wearables[(int)AppearanceLayer.PANTS].AssetID = value; } 150 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
267 } 151 }
268 152
269 public virtual UUID ShoesItem { 153 public virtual UUID ShoesItem {
270 get { return m_wearables[(int)AppearanceLayer.SHOES].ItemID; } 154 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
271 set { m_wearables[(int)AppearanceLayer.SHOES].ItemID = value; } 155 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
272 } 156 }
273 157
274 public virtual UUID ShoesAsset { 158 public virtual UUID ShoesAsset {
275 get { return m_wearables[(int)AppearanceLayer.SHOES].AssetID; } 159 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
276 set { m_wearables[(int)AppearanceLayer.SHOES].AssetID = value; } 160 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
277 } 161 }
278 162
279 public virtual UUID SocksItem { 163 public virtual UUID SocksItem {
280 get { return m_wearables[(int)AppearanceLayer.SOCKS].ItemID; } 164 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
281 set { m_wearables[(int)AppearanceLayer.SOCKS].ItemID = value; } 165 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
282 } 166 }
283 167
284 public virtual UUID SocksAsset { 168 public virtual UUID SocksAsset {
285 get { return m_wearables[(int)AppearanceLayer.SOCKS].AssetID; } 169 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
286 set { m_wearables[(int)AppearanceLayer.SOCKS].AssetID = value; } 170 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
287 } 171 }
288 172
289 public virtual UUID JacketItem { 173 public virtual UUID JacketItem {
290 get { return m_wearables[(int)AppearanceLayer.JACKET].ItemID; } 174 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
291 set { m_wearables[(int)AppearanceLayer.JACKET].ItemID = value; } 175 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
292 } 176 }
293 177
294 public virtual UUID JacketAsset { 178 public virtual UUID JacketAsset {
295 get { return m_wearables[(int)AppearanceLayer.JACKET].AssetID; } 179 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
296 set { m_wearables[(int)AppearanceLayer.JACKET].AssetID = value; } 180 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
297 } 181 }
298 182
299 public virtual UUID GlovesItem { 183 public virtual UUID GlovesItem {
300 get { return m_wearables[(int)AppearanceLayer.GLOVES].ItemID; } 184 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
301 set { m_wearables[(int)AppearanceLayer.GLOVES].ItemID = value; } 185 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
302 } 186 }
303 187
304 public virtual UUID GlovesAsset { 188 public virtual UUID GlovesAsset {
305 get { return m_wearables[(int)AppearanceLayer.GLOVES].AssetID; } 189 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
306 set { m_wearables[(int)AppearanceLayer.GLOVES].AssetID = value; } 190 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
307 } 191 }
308 192
309 public virtual UUID UnderShirtItem { 193 public virtual UUID UnderShirtItem {
310 get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID; } 194 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
311 set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID = value; } 195 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
312 } 196 }
313 197
314 public virtual UUID UnderShirtAsset { 198 public virtual UUID UnderShirtAsset {
315 get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID; } 199 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
316 set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID = value; } 200 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
317 } 201 }
318 202
319 public virtual UUID UnderPantsItem { 203 public virtual UUID UnderPantsItem {
320 get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID; } 204 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
321 set { m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID = value; } 205 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
322 } 206 }
323 207
324 public virtual UUID UnderPantsAsset { 208 public virtual UUID UnderPantsAsset {
325 get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID; } 209 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
326 set { m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID = value; } 210 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
327 } 211 }
328 212
329 public virtual UUID SkirtItem { 213 public virtual UUID SkirtItem {
330 get { return m_wearables[(int)AppearanceLayer.SKIRT].ItemID; } 214 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
331 set { m_wearables[(int)AppearanceLayer.SKIRT].ItemID = value; } 215 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
332 } 216 }
333 217
334 public virtual UUID SkirtAsset { 218 public virtual UUID SkirtAsset {
335 get { return m_wearables[(int)AppearanceLayer.SKIRT].AssetID; } 219 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
336 set { m_wearables[(int)AppearanceLayer.SKIRT].AssetID = value; } 220 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
337 }
338
339 public virtual void SetDefaultWearables()
340 {
341 m_wearables[(int)AppearanceLayer.BODY].AssetID = BODY_ASSET;
342 m_wearables[(int)AppearanceLayer.BODY].ItemID = BODY_ITEM;
343 m_wearables[(int)AppearanceLayer.SKIN].AssetID = SKIN_ASSET;
344 m_wearables[(int)AppearanceLayer.SKIN].ItemID = SKIN_ITEM;
345 m_wearables[(int)AppearanceLayer.HAIR].AssetID = HAIR_ASSET;
346 m_wearables[(int)AppearanceLayer.HAIR].ItemID = HAIR_ITEM;
347 m_wearables[(int)AppearanceLayer.SHIRT].AssetID = SHIRT_ASSET;
348 m_wearables[(int)AppearanceLayer.SHIRT].ItemID = SHIRT_ITEM;
349 m_wearables[(int)AppearanceLayer.PANTS].AssetID = PANTS_ASSET;
350 m_wearables[(int)AppearanceLayer.PANTS].ItemID = PANTS_ITEM;
351 m_wearables[(int)AppearanceLayer.ALPHA].AssetID = ALPHA_ASSET;
352 m_wearables[(int)AppearanceLayer.ALPHA].ItemID = ALPHA_ITEM;
353 m_wearables[(int)AppearanceLayer.TATTOO].AssetID = TATTOO_ASSET;
354 m_wearables[(int)AppearanceLayer.TATTOO].ItemID = TATTOO_ITEM;
355 }
356
357 public virtual void ClearWearables()
358 {
359 for (int i = 0; i < m_wearables.Length ; i++)
360 {
361 m_wearables[i].AssetID = UUID.Zero;
362 m_wearables[i].ItemID = UUID.Zero;
363 }
364 }
365
366 public virtual void SetDefaultParams(byte[] vparams)
367 {
368 // TODO: Figure out better values then 'fat scientist 150' or 'alien 0'
369 for (int i = 0; i < VISUALPARAM_COUNT; i++)
370 {
371 vparams[i] = 150;
372 }
373 }
374
375 protected Primitive.TextureEntry m_texture;
376
377 public virtual Primitive.TextureEntry Texture
378 {
379 get { return m_texture; }
380 set { m_texture = value; }
381 } 221 }
382 222
383 protected float m_avatarHeight = 0;
384 protected float m_hipOffset = 0;
385
386 public virtual float AvatarHeight 223 public virtual float AvatarHeight
387 { 224 {
388 get { return m_avatarHeight; } 225 get { return m_avatarHeight; }
@@ -398,41 +235,213 @@ namespace OpenSim.Framework
398 235
399 public AvatarAppearance(UUID owner) 236 public AvatarAppearance(UUID owner)
400 { 237 {
401 m_wearables = new AvatarWearable[(int)AppearanceLayer.MAX_WEARABLES]; 238// DEBUG ON
402 for (int i = 0; i < (int)AppearanceLayer.MAX_WEARABLES; i++) 239 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
403 { 240// DEBUG OFF
404 // this makes them all null
405 m_wearables[i] = new AvatarWearable();
406 }
407 m_serial = 0; 241 m_serial = 0;
408 m_owner = owner; 242 m_owner = owner;
409 //BuildVisualParamEnum() 243
410 m_visualparams = new byte[VISUALPARAM_COUNT];
411 // This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
412 SetDefaultParams(m_visualparams);
413 SetDefaultWearables(); 244 SetDefaultWearables();
414 m_texture = GetDefaultTexture(); 245 SetDefaultTexture();
246 SetDefaultParams();
247 SetHeight();
248
249 m_attachments = new Dictionary<int, AvatarAttachment>();
415 } 250 }
416 251
417 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 252 public AvatarAppearance(UUID avatarID, OSDMap map)
418 { 253 {
254// DEBUG ON
255 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
256// DEBUG OFF
419 m_owner = avatarID; 257 m_owner = avatarID;
420 m_serial = 1; 258 Unpack(map);
421 m_wearables = wearables; 259 SetHeight();
422 m_visualparams = visualParams;
423 m_texture = GetDefaultTexture();
424 } 260 }
425 261
426 /// <summary> 262 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
427 /// Set up appearance textures and avatar parameters, including a height calculation
428 /// </summary>
429 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
430 { 263 {
264// DEBUG ON
265 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
266// DEBUG OFF
267 m_serial = 1;
268 m_owner = avatarID;
269
270 if (wearables != null)
271 m_wearables = wearables;
272 else
273 SetDefaultWearables();
274
431 if (textureEntry != null) 275 if (textureEntry != null)
432 m_texture = textureEntry; 276 m_texture = textureEntry;
277 else
278 SetDefaultTexture();
279
433 if (visualParams != null) 280 if (visualParams != null)
434 m_visualparams = visualParams; 281 m_visualparams = visualParams;
282 else
283 SetDefaultParams();
284
285 SetHeight();
286
287 m_attachments = new Dictionary<int, AvatarAttachment>();
288 }
289
290 public AvatarAppearance(AvatarAppearance appearance)
291 {
292// DEBUG ON
293 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
294// DEBUG OFF
295 if (appearance == null)
296 {
297 m_serial = 0;
298 m_owner = UUID.Zero;
299
300 SetDefaultWearables();
301 SetDefaultTexture();
302 SetDefaultParams();
303 SetHeight();
304
305 m_attachments = new Dictionary<int, AvatarAttachment>();
306
307 return;
308 }
309
310 m_serial = appearance.Serial;
311 m_owner = appearance.Owner;
312
313 m_wearables = null;
314 if (appearance.Wearables != null)
315 {
316 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
317 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
318 SetWearable(i,appearance.Wearables[i]);
319 }
320
321 m_texture = null;
322 if (appearance.Texture != null)
323 {
324 byte[] tbytes = appearance.Texture.GetBytes();
325 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
326 }
327
328 m_visualparams = null;
329 if (appearance.VisualParams != null)
330 m_visualparams = (byte[])appearance.VisualParams.Clone();
331
332 m_attachments = new Dictionary<int, AvatarAttachment>();
333 foreach (KeyValuePair<int, AvatarAttachment> kvp in appearance.Attachments)
334 m_attachments[kvp.Key] = new AvatarAttachment(kvp.Value);
335 }
336
337 protected virtual void SetDefaultWearables()
338 {
339 m_wearables = AvatarWearable.DefaultWearables;
340 }
341
342 protected virtual void SetDefaultParams()
343 {
344 m_visualparams = new byte[VISUALPARAM_COUNT];
345 for (int i = 0; i < VISUALPARAM_COUNT; i++)
346 {
347 m_visualparams[i] = 150;
348 }
349 }
350
351 protected virtual void SetDefaultTexture()
352 {
353 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
354 // The initialization of these seems to force a rebake regardless of whether it is needed
355 // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
356 // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
357 // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
358 // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
359 // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
360 // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
361 // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
362 }
363
364 /// <summary>
365 /// Set up appearance textures.
366 /// Returns boolean that indicates whether the new entries actually change the
367 /// existing values.
368 /// </summary>
369 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
370 {
371 if (textureEntry == null)
372 return false;
373
374 // There are much simpler versions of this copy that could be
375 // made. We determine if any of the textures actually
376 // changed to know if the appearance should be saved later
377 bool changed = false;
378 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
379 {
380 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
381 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
382
383 if (newface == null)
384 {
385 if (oldface == null) continue;
386 }
387 else
388 {
389 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
390 }
391
392 m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
393 changed = true;
394// DEBUG ON
395 if (newface != null)
396 m_log.WarnFormat("[SCENEPRESENCE] index {0}, new texture id {1}",i,newface.TextureID);
397// DEBUG OFF
398 }
399
400 return changed;
401 }
402
403 /// <summary>
404 /// Set up visual parameters for the avatar and refresh the avatar height
405 /// Returns boolean that indicates whether the new entries actually change the
406 /// existing values.
407 /// </summary>
408 public virtual bool SetVisualParams(byte[] visualParams)
409 {
410 if (visualParams == null)
411 return false;
412
413 // There are much simpler versions of this copy that could be
414 // made. We determine if any of the visual parameters actually
415 // changed to know if the appearance should be saved later
416 bool changed = false;
417 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
418 {
419 if (visualParams[i] != m_visualparams[i])
420 {
421// DEBUG ON
422 m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
423 i,m_visualparams[i],visualParams[i]);
424// DEBUG OFF
425 m_visualparams[i] = visualParams[i];
426 changed = true;
427 }
428 }
429
430 // Reset the height if the visual parameters actually changed
431 if (changed)
432 SetHeight();
435 433
434 return changed;
435 }
436
437 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
438 {
439 SetTextureEntries(textureEntry);
440 SetVisualParams(visualParams);
441 }
442
443 public virtual void SetHeight()
444 {
436 m_avatarHeight = 1.23077f // Shortest possible avatar height 445 m_avatarHeight = 1.23077f // Shortest possible avatar height
437 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height 446 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
438 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size 447 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
@@ -440,102 +449,63 @@ namespace OpenSim.Framework
440 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height 449 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
441 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height 450 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
442 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length 451 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
452
443 m_hipOffset = (((1.23077f // Half of avatar 453 m_hipOffset = (((1.23077f // Half of avatar
444 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height 454 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
445 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length 455 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
446 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height 456 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
447 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height 457 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
448 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f; 458 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
449
450
451
452 //System.Console.WriteLine(">>>>>>> [APPEARANCE]: Height {0} Hip offset {1}" + m_avatarHeight + " " + m_hipOffset);
453 //m_log.Debug("------------- Set Appearance Texture ---------------");
454 //Primitive.TextureEntryFace[] faces = Texture.FaceTextures;
455 //foreach (Primitive.TextureEntryFace face in faces)
456 //{
457 // if (face != null)
458 // m_log.Debug(" ++ " + face.TextureID);
459 // else
460 // m_log.Debug(" ++ NULL ");
461 //}
462 //m_log.Debug("----------------------------");
463
464 } 459 }
465 460
466 public virtual void SetWearable(int wearableId, AvatarWearable wearable) 461 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
467 { 462 {
468 m_wearables[wearableId] = wearable; 463// DEBUG ON
464// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
465// DEBUG OFF
466 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
469 } 467 }
470 468
471 public static Primitive.TextureEntry GetDefaultTexture()
472 {
473 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
474 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
475 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
476 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
477 textu.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
478 textu.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
479 textu.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
480 textu.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
481 return textu;
482 }
483 469
484 public static byte[] GetDefaultVisualParams() 470// DEBUG ON
471 public override String ToString()
485 { 472 {
486 byte[] visualParams; 473 String s = "";
487 visualParams = new byte[VISUALPARAM_COUNT]; 474 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
488 for (int i = 0; i < VISUALPARAM_COUNT; i++) 475 if (m_texture.FaceTextures[i] != null)
489 { 476 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
490 visualParams[i] = 100; 477
491 } 478 foreach (AvatarWearable awear in m_wearables)
492 return visualParams; 479 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
480
481 s += "Visual Params: ";
482 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
483 s += String.Format("{0},",m_visualparams[j]);
484 s += "\n";
485
486 return s;
493 } 487 }
488// DEBUG OFF
494 489
495 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 490 public void SetAttachments(AvatarAttachment[] data)
496
497 public void SetAttachments(AttachmentData[] data)
498 { 491 {
499 foreach (AttachmentData a in data) 492 foreach (AvatarAttachment attach in data)
500 { 493 m_attachments[attach.AttachPoint] = new AvatarAttachment(attach);
501 m_attachments[a.AttachPoint] = new UUID[2];
502 m_attachments[a.AttachPoint][0] = a.ItemID;
503 m_attachments[a.AttachPoint][1] = a.AssetID;
504 }
505 } 494 }
506 495
507 public void SetAttachments(Hashtable data) 496 public void SetAttachment(int attachpoint, UUID item, UUID asset)
508 { 497 {
509 m_attachments.Clear(); 498 if (attachpoint == 0)
510
511 if (data == null)
512 return; 499 return;
513 500
514 foreach (DictionaryEntry e in data) 501 if (item == UUID.Zero)
515 { 502 {
516 int attachpoint = Convert.ToInt32(e.Key);
517
518 if (m_attachments.ContainsKey(attachpoint)) 503 if (m_attachments.ContainsKey(attachpoint))
519 continue; 504 m_attachments.Remove(attachpoint);
520 505 return;
521 UUID item;
522 UUID asset;
523
524 Hashtable uuids = (Hashtable) e.Value;
525 UUID.TryParse(uuids["item"].ToString(), out item);
526 UUID.TryParse(uuids["asset"].ToString(), out asset);
527
528 UUID[] attachment = new UUID[2];
529 attachment[0] = item;
530 attachment[1] = asset;
531
532 m_attachments[attachpoint] = attachment;
533 } 506 }
534 }
535 507
536 public Dictionary<int, UUID[]> GetAttachmentDictionary() 508 m_attachments[attachpoint] = new AvatarAttachment(attachpoint,item,asset);
537 {
538 return m_attachments;
539 } 509 }
540 510
541 public Hashtable GetAttachments() 511 public Hashtable GetAttachments()
@@ -545,16 +515,13 @@ namespace OpenSim.Framework
545 515
546 Hashtable ret = new Hashtable(); 516 Hashtable ret = new Hashtable();
547 517
548 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 518 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
549 { 519 {
550 int attachpoint = kvp.Key;
551 UUID[] uuids = kvp.Value;
552
553 Hashtable data = new Hashtable(); 520 Hashtable data = new Hashtable();
554 data["item"] = uuids[0].ToString(); 521 data["item"] = kvp.Value.ItemID.ToString();
555 data["asset"] = uuids[1].ToString(); 522 data["asset"] = kvp.Value.AssetID.ToString();
556 523
557 ret[attachpoint] = data; 524 ret[kvp.Key] = data;
558 } 525 }
559 526
560 return ret; 527 return ret;
@@ -570,7 +537,7 @@ namespace OpenSim.Framework
570 if (!m_attachments.ContainsKey(attachpoint)) 537 if (!m_attachments.ContainsKey(attachpoint))
571 return UUID.Zero; 538 return UUID.Zero;
572 539
573 return m_attachments[attachpoint][0]; 540 return m_attachments[attachpoint].ItemID;
574 } 541 }
575 542
576 public UUID GetAttachedAsset(int attachpoint) 543 public UUID GetAttachedAsset(int attachpoint)
@@ -578,33 +545,14 @@ namespace OpenSim.Framework
578 if (!m_attachments.ContainsKey(attachpoint)) 545 if (!m_attachments.ContainsKey(attachpoint))
579 return UUID.Zero; 546 return UUID.Zero;
580 547
581 return m_attachments[attachpoint][1]; 548 return m_attachments[attachpoint].AssetID;
582 }
583
584 public void SetAttachment(int attachpoint, UUID item, UUID asset)
585 {
586 if (attachpoint == 0)
587 return;
588
589 if (item == UUID.Zero)
590 {
591 if (m_attachments.ContainsKey(attachpoint))
592 m_attachments.Remove(attachpoint);
593 return;
594 }
595
596 if (!m_attachments.ContainsKey(attachpoint))
597 m_attachments[attachpoint] = new UUID[2];
598
599 m_attachments[attachpoint][0] = item;
600 m_attachments[attachpoint][1] = asset;
601 } 549 }
602 550
603 public int GetAttachpoint(UUID itemID) 551 public int GetAttachpoint(UUID itemID)
604 { 552 {
605 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 553 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
606 { 554 {
607 if (kvp.Value[0] == itemID) 555 if (kvp.Value.ItemID == itemID)
608 { 556 {
609 return kvp.Key; 557 return kvp.Key;
610 } 558 }
@@ -625,42 +573,126 @@ namespace OpenSim.Framework
625 m_attachments.Clear(); 573 m_attachments.Clear();
626 } 574 }
627 575
628 string GetAttachmentsString() 576 /// <summary>
577 /// Create an OSDMap from the appearance data
578 /// </summary>
579 public OSDMap Pack()
629 { 580 {
630 List<string> strings = new List<string>(); 581 OSDMap data = new OSDMap();
631 582
632 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 583 data["serial"] = OSD.FromInteger(m_serial);
584 data["height"] = OSD.FromReal(m_avatarHeight);
585 data["hipoffset"] = OSD.FromReal(m_hipOffset);
586
587 // Wearables
588 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
589 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
590 wears.Add(m_wearables[i].Pack());
591 data["wearables"] = wears;
592
593 // Avatar Textures
594 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
595 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
633 { 596 {
634 strings.Add(e.Key.ToString()); 597 if (m_texture.FaceTextures[i] != null)
635 strings.Add(e.Value[0].ToString()); 598 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
636 strings.Add(e.Value[1].ToString()); 599 else
600 textures.Add(OSD.FromUUID(UUID.Zero));
637 } 601 }
602 data["textures"] = textures;
638 603
639 return String.Join(",", strings.ToArray()); 604 // Visual Parameters
605 OSDBinary visualparams = new OSDBinary(m_visualparams);
606 data["visualparams"] = visualparams;
607
608 // Attachments
609 OSDArray attachs = new OSDArray(m_attachments.Count);
610 foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
611 attachs.Add(kvp.Value.Pack());
612 data["attachments"] = attachs;
613
614 return data;
640 } 615 }
641 616
642 void SetAttachmentsString(string data) 617 /// <summary>
618 /// Unpack and OSDMap and initialize the appearance
619 /// from it
620 /// </summary>
621 public void Unpack(OSDMap data)
643 { 622 {
644 string[] strings = data.Split(new char[] {','}); 623 if ((data != null) && (data["appearance_serial"] != null))
645 int i = 0; 624 m_serial = data["appearance_serial"].AsInteger();
625 if ((data != null) && (data["height"] != null))
626 m_avatarHeight = (float)data["height"].AsReal();
627 if ((data != null) && (data["hipoffset"] != null))
628 m_hipOffset = (float)data["hipoffset"].AsReal();
629
630 try
631 {
632 // Wearables
633 SetDefaultWearables();
634 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
635 {
636 OSDArray wears = (OSDArray)(data["wearables"]);
637 for (int i = 0; i < wears.Count; i++)
638 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
639 }
640 else
641 {
642 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
643 }
646 644
647 m_attachments.Clear(); 645 // Avatar Textures
646 SetDefaultTexture();
647 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
648 {
649 OSDArray textures = (OSDArray)(data["textures"]);
650 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
651 {
652 if (textures[i] != null)
653 {
654 UUID textureID = textures[i].AsUUID();
655 if (textureID != UUID.Zero)
656 m_texture.CreateFace((uint)i).TextureID = textureID;
657 }
658 }
659 }
660 else
661 {
662 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
663 }
648 664
649 while (strings.Length - i > 2) 665 // Visual Parameters
650 { 666 SetDefaultParams();
651 int attachpoint = Int32.Parse(strings[i]); 667 if ((data != null) && (data["visualparams"] != null))
652 UUID item = new UUID(strings[i+1]); 668 {
653 UUID asset = new UUID(strings[i+2]); 669 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
654 i += 3; 670 m_visualparams = data["visualparams"].AsBinary();
671 }
672 else
673 {
674 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
675 }
655 676
656 if (!m_attachments.ContainsKey(attachpoint)) 677 // Attachments
678 m_attachments = new Dictionary<int, AvatarAttachment>();
679 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
657 { 680 {
658 m_attachments[attachpoint] = new UUID[2]; 681 OSDArray attachs = (OSDArray)(data["attachments"]);
659 m_attachments[attachpoint][0] = item; 682 for (int i = 0; i < attachs.Count; i++)
660 m_attachments[attachpoint][1] = asset; 683 {
684 AvatarAttachment attach = new AvatarAttachment((OSDMap)attachs[i]);
685 m_attachments[attach.AttachPoint] = attach;
686 }
661 } 687 }
662 } 688 }
689 catch (Exception e)
690 {
691 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
692 }
663 } 693 }
694
695
664 /// <summary> 696 /// <summary>
665 /// Viewer Params Array Element for AgentSetAppearance 697 /// Viewer Params Array Element for AgentSetAppearance
666 /// Generated from LibOMV's Visual Params list 698 /// Generated from LibOMV's Visual Params list
@@ -1424,4 +1456,4 @@ namespace OpenSim.Framework
1424 SKIRT_SKIRT_BLUE = 217 1456 SKIRT_SKIRT_BLUE = 217
1425 } 1457 }
1426 } 1458 }
1427} 1459} \ No newline at end of file