OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
AnimationSet.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Text;
32 using log4net;
33 using OpenMetaverse;
34 using OpenMetaverse.StructuredData;
35 
36 using OpenSim.Framework;
37 
39 
40 namespace OpenSim.Region.Framework.Scenes.Animation
41 {
42  [Serializable]
43  public class AnimationSet
44  {
45 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
47  private OpenSim.Framework.Animation m_implicitDefaultAnimation = new OpenSim.Framework.Animation();
48  private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
49  private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
50 
51  public OpenSim.Framework.Animation DefaultAnimation
52  {
53  get { return m_defaultAnimation; }
54  }
55 
56  public OpenSim.Framework.Animation ImplicitDefaultAnimation
57  {
58  get { return m_implicitDefaultAnimation; }
59  }
60 
61  public AnimationSet()
62  {
63  ResetDefaultAnimation();
64  }
65 
66  public AnimationSet(OSDArray pArray)
67  {
68  ResetDefaultAnimation();
69  FromOSDArray(pArray);
70  }
71 
72  public bool HasAnimation(UUID animID)
73  {
74  if (m_defaultAnimation.AnimID == animID)
75  return true;
76 
77  for (int i = 0; i < m_animations.Count; ++i)
78  {
79  if (m_animations[i].AnimID == animID)
80  return true;
81  }
82 
83  return false;
84  }
85 
86  public bool Add(UUID animID, int sequenceNum, UUID objectID)
87  {
88  lock (m_animations)
89  {
90  if (!HasAnimation(animID))
91  {
92  m_animations.Add(new OpenSim.Framework.Animation(animID, sequenceNum, objectID));
93  return true;
94  }
95  }
96  return false;
97  }
98 
107  public bool Remove(UUID animID, bool allowNoDefault)
108  {
109  lock (m_animations)
110  {
111  if (m_defaultAnimation.AnimID == animID)
112  {
113  if (allowNoDefault)
114  m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
115  else
116  ResetDefaultAnimation();
117  }
118  else if (HasAnimation(animID))
119  {
120  for (int i = 0; i < m_animations.Count; i++)
121  {
122  if (m_animations[i].AnimID == animID)
123  {
124  m_animations.RemoveAt(i);
125  return true;
126  }
127  }
128  }
129  }
130  return false;
131  }
132 
133  public void Clear()
134  {
135  ResetDefaultAnimation();
136  m_animations.Clear();
137  }
138 
143  public bool SetDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
144  {
145  if (m_defaultAnimation.AnimID != animID)
146  {
147  m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
148  m_implicitDefaultAnimation = m_defaultAnimation;
149  return true;
150  }
151  return false;
152  }
153 
154  // Called from serialization only
155  public void SetImplicitDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
156  {
157  m_implicitDefaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
158  }
159 
160  protected bool ResetDefaultAnimation()
161  {
162  return TrySetDefaultAnimation("STAND", 1, UUID.Zero);
163  }
164 
168  public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
169  {
170 // m_log.DebugFormat(
171 // "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
172 // anim, sequenceNum, objectID);
173 
174  if (DefaultAvatarAnimations.AnimsUUID.ContainsKey(anim))
175  {
176  return SetDefaultAnimation(DefaultAvatarAnimations.AnimsUUID[anim], sequenceNum, objectID);
177  }
178  return false;
179  }
180 
181  public void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
182  {
183  lock (m_animations)
184  {
185  int defaultSize = 0;
186  if (m_defaultAnimation.AnimID != UUID.Zero)
187  defaultSize++;
188 
189  animIDs = new UUID[m_animations.Count + defaultSize];
190  sequenceNums = new int[m_animations.Count + defaultSize];
191  objectIDs = new UUID[m_animations.Count + defaultSize];
192 
193  if (m_defaultAnimation.AnimID != UUID.Zero)
194  {
195  animIDs[0] = m_defaultAnimation.AnimID;
196  sequenceNums[0] = m_defaultAnimation.SequenceNum;
197  objectIDs[0] = m_defaultAnimation.ObjectID;
198  }
199 
200  for (int i = 0; i < m_animations.Count; ++i)
201  {
202  animIDs[i + defaultSize] = m_animations[i].AnimID;
203  sequenceNums[i + defaultSize] = m_animations[i].SequenceNum;
204  objectIDs[i + defaultSize] = m_animations[i].ObjectID;
205  }
206  }
207  }
208 
210  {
211  OpenSim.Framework.Animation[] theArray = new OpenSim.Framework.Animation[m_animations.Count];
212  uint i = 0;
213  try
214  {
215  foreach (OpenSim.Framework.Animation anim in m_animations)
216  theArray[i++] = anim;
217  }
218  catch
219  {
220  /* S%^t happens. Ignore. */
221  }
222  return theArray;
223  }
224 
225  public void FromArray(OpenSim.Framework.Animation[] theArray)
226  {
227  foreach (OpenSim.Framework.Animation anim in theArray)
228  m_animations.Add(anim);
229  }
230 
231  // Create representation of this AnimationSet as an OSDArray.
232  // First two entries in the array are the default and implicitDefault animations
233  // followed by the other animations.
235  {
236  OSDArray ret = new OSDArray();
237  ret.Add(DefaultAnimation.PackUpdateMessage());
238  ret.Add(ImplicitDefaultAnimation.PackUpdateMessage());
239 
240  foreach (OpenSim.Framework.Animation anim in m_animations)
241  ret.Add(anim.PackUpdateMessage());
242 
243  return ret;
244  }
245 
246  public void FromOSDArray(OSDArray pArray)
247  {
248  this.Clear();
249 
250  if (pArray.Count >= 1)
251  {
252  m_defaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[0]);
253  }
254  if (pArray.Count >= 2)
255  {
256  m_implicitDefaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[1]);
257  }
258  for (int ii = 2; ii < pArray.Count; ii++)
259  {
260  m_animations.Add(new OpenSim.Framework.Animation((OSDMap)pArray[ii]));
261  }
262  }
263 
264  // Compare two AnimationSets and return 'true' if the default animations are the same
265  // and all of the animations in the list are equal.
266  public override bool Equals(object obj)
267  {
268  AnimationSet other = obj as AnimationSet;
269  if (other != null)
270  {
271  if (this.DefaultAnimation.Equals(other.DefaultAnimation)
272  && this.ImplicitDefaultAnimation.Equals(other.ImplicitDefaultAnimation))
273  {
274  // The defaults are the same. Is the list of animations the same?
275  OpenSim.Framework.Animation[] thisAnims = this.ToArray();
276  OpenSim.Framework.Animation[] otherAnims = other.ToArray();
277  if (thisAnims.Length == 0 && otherAnims.Length == 0)
278  return true; // the common case
279  if (thisAnims.Length == otherAnims.Length)
280  {
281  // Do this the hard way but since the list is usually short this won't take long.
282  foreach (OpenSim.Framework.Animation thisAnim in thisAnims)
283  {
284  bool found = false;
285  foreach (OpenSim.Framework.Animation otherAnim in otherAnims)
286  {
287  if (thisAnim.Equals(otherAnim))
288  {
289  found = true;
290  break;
291  }
292  }
293  if (!found)
294  {
295  // If anything is not in the other list, these are not equal
296  return false;
297  }
298  }
299  // Found everything in the other list. Since lists are equal length, they must be equal.
300  return true;
301  }
302  }
303  return false;
304  }
305  // Don't know what was passed, but the base system will figure it out for me.
306  return base.Equals(obj);
307  }
308 
309  public override int GetHashCode()
310  {
311  return base.GetHashCode();
312  }
313 
314  public override string ToString()
315  {
316  StringBuilder buff = new StringBuilder();
317  buff.Append("dflt=");
318  buff.Append(DefaultAnimation.ToString());
319  buff.Append(",iDflt=");
320  if (DefaultAnimation.Equals(ImplicitDefaultAnimation))
321  buff.Append("same");
322  else
323  buff.Append(ImplicitDefaultAnimation.ToString());
324  if (m_animations.Count > 0)
325  {
326  buff.Append(",anims=");
327  bool firstTime = true;
328  foreach (OpenSim.Framework.Animation anim in m_animations)
329  {
330  if (!firstTime)
331  buff.Append(",");
332  buff.Append("<");
333  buff.Append(anim.ToString());
334  buff.Append(">");
335  firstTime = false;
336  }
337  }
338  return buff.ToString();
339  }
340  }
341 }
OpenMetaverse.StructuredData.OSDArray OSDArray
void SetImplicitDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
Information about an Animation
Definition: Animation.cs:38
OpenMetaverse.StructuredData.OSDMap OSDMap
bool Remove(UUID animID, bool allowNoDefault)
Remove the specified animation
bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
Set the animation as the default animation if it's known
bool Add(UUID animID, int sequenceNum, UUID objectID)
Definition: AnimationSet.cs:86
void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
OpenSim.Framework.Animation Animation
Definition: AnimationSet.cs:38
void FromArray(OpenSim.Framework.Animation[] theArray)
Interactive OpenSim region server
Definition: OpenSim.cs:55
bool SetDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
The default animation is reserved for "main" animations that are mutually exclusive, e.g. flying and sitting.
OpenSim.Region.Framework.Scenes.Animation.AnimationSet AnimationSet