diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs new file mode 100644 index 0000000..eb1a970 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | |||
@@ -0,0 +1,341 @@ | |||
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 | |||
38 | using Animation = OpenSim.Framework.Animation; | ||
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 | |||
99 | /// <summary> | ||
100 | /// Remove the specified animation | ||
101 | /// </summary> | ||
102 | /// <param name='animID'></param> | ||
103 | /// <param name='allowNoDefault'> | ||
104 | /// If true, then the default animation can be entirely removed. | ||
105 | /// If false, then removing the default animation will reset it to the simulator default (currently STAND). | ||
106 | /// </param> | ||
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 | |||
139 | /// <summary> | ||
140 | /// The default animation is reserved for "main" animations | ||
141 | /// that are mutually exclusive, e.g. flying and sitting. | ||
142 | /// </summary> | ||
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 | |||
165 | /// <summary> | ||
166 | /// Set the animation as the default animation if it's known | ||
167 | /// </summary> | ||
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 | |||
209 | public OpenSim.Framework.Animation[] ToArray() | ||
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. | ||
234 | public OSDArray ToOSDArray() | ||
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 | } | ||