opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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.Linq;
31 using System.Reflection;
32 using System.Threading;
33 using log4net;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Region.Physics.Manager;
39  
40 namespace OpenSim.Region.Framework.Scenes.Animation
41 {
42 /// <summary>
43 /// Handle all animation duties for a scene presence
44 /// </summary>
45 public class ScenePresenceAnimator
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48  
49 public AnimationSet Animations
50 {
51 get { return m_animations; }
52 }
53 protected AnimationSet m_animations = new AnimationSet();
54  
55 /// <value>
56 /// The current movement animation
57 /// </value>
58 public string CurrentMovementAnimation { get; private set; }
59  
60 private int m_animTickFall;
61 public int m_animTickJump; // ScenePresence has to see this to control +Z force
62 public bool m_jumping = false;
63 public float m_jumpVelocity = 0f;
64 // private int m_landing = 0;
65  
66 /// <summary>
67 /// Is the avatar falling?
68 /// </summary>
69 public bool Falling { get; private set; }
70  
71 private float m_fallHeight;
72  
73 /// <value>
74 /// The scene presence that this animator applies to
75 /// </value>
76 protected ScenePresence m_scenePresence;
77  
78 public ScenePresenceAnimator(ScenePresence sp)
79 {
80 m_scenePresence = sp;
81 CurrentMovementAnimation = "CROUCH";
82 }
83  
84 public void AddAnimation(UUID animID, UUID objectID)
85 {
86 if (m_scenePresence.IsChildAgent)
87 return;
88  
89 if (m_scenePresence.Scene.DebugAnimations)
90 m_log.DebugFormat(
91 "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}",
92 GetAnimName(animID), animID, m_scenePresence.Name);
93  
94 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
95 {
96 SendAnimPack();
97 m_scenePresence.TriggerScenePresenceUpdated();
98 }
99 }
100  
101 // Called from scripts
102 public void AddAnimation(string name, UUID objectID)
103 {
104 if (m_scenePresence.IsChildAgent)
105 return;
106  
107 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
108 // are referenced with lower case names!
109 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
110 if (animID == UUID.Zero)
111 return;
112  
113 // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
114  
115 AddAnimation(animID, objectID);
116 }
117  
118 /// <summary>
119 /// Remove the specified animation
120 /// </summary>
121 /// <param name='animID'></param>
122 /// <param name='allowNoDefault'>
123 /// If true, then the default animation can be entirely removed.
124 /// If false, then removing the default animation will reset it to the simulator default (currently STAND).
125 /// </param>
126 public void RemoveAnimation(UUID animID, bool allowNoDefault)
127 {
128 if (m_scenePresence.IsChildAgent)
129 return;
130  
131 if (m_scenePresence.Scene.DebugAnimations)
132 m_log.DebugFormat(
133 "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}",
134 GetAnimName(animID), animID, m_scenePresence.Name);
135  
136 if (m_animations.Remove(animID, allowNoDefault))
137 {
138 SendAnimPack();
139 m_scenePresence.TriggerScenePresenceUpdated();
140 }
141 }
142  
143 // Called from scripts
144 public void RemoveAnimation(string name)
145 {
146 if (m_scenePresence.IsChildAgent)
147 return;
148  
149 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
150 // are referenced with lower case names!
151 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
152 if (animID == UUID.Zero)
153 return;
154  
155 RemoveAnimation(animID, true);
156 }
157  
158 public void ResetAnimations()
159 {
160 if (m_scenePresence.Scene.DebugAnimations)
161 m_log.DebugFormat(
162 "[SCENE PRESENCE ANIMATOR]: Resetting animations for {0} in {1}",
163 m_scenePresence.Name, m_scenePresence.Scene.RegionInfo.RegionName);
164  
165 m_animations.Clear();
166 }
167  
168 /// <summary>
169 /// The movement animation is reserved for "main" animations
170 /// that are mutually exclusive, e.g. flying and sitting.
171 /// </summary>
172 /// <returns>'true' if the animation was updated</returns>
173 public bool TrySetMovementAnimation(string anim)
174 {
175 bool ret = false;
176 if (!m_scenePresence.IsChildAgent)
177 {
178 // m_log.DebugFormat(
179 // "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}",
180 // anim, m_scenePresence.Name);
181  
182 if (m_animations.TrySetDefaultAnimation(
183 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
184 {
185 // m_log.DebugFormat(
186 // "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
187 // anim, m_scenePresence.Name);
188  
189 // 16384 is CHANGED_ANIMATION
190 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION});
191 SendAnimPack();
192 ret = true;
193 }
194 }
195 else
196 {
197 m_log.WarnFormat(
198 "[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}",
199 anim, m_scenePresence.Name);
200 }
201 return ret;
202 }
203  
204 /// <summary>
205 /// This method determines the proper movement related animation
206 /// </summary>
207 private string DetermineMovementAnimation()
208 {
209 const float FALL_DELAY = 800f;
210 const float PREJUMP_DELAY = 200f;
211 const float JUMP_PERIOD = 800f;
212 #region Inputs
213  
214 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
215 PhysicsActor actor = m_scenePresence.PhysicsActor;
216  
217 // Create forward and left vectors from the current avatar rotation
218 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
219 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
220 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
221  
222 // Check control flags
223 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
224 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
225 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
226 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
227 bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
228 bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
229 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
230 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
231 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
232 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
233 if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown)
234 {
235 heldTurnLeft = false;
236 heldTurnRight = false;
237 }
238  
239 // Direction in which the avatar is trying to move
240 Vector3 move = Vector3.Zero;
241 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
242 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
243 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
244 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
245 if (heldUp) { move.Z += 1; }
246 if (heldDown) { move.Z -= 1; }
247  
248 // Is the avatar trying to move?
249 // bool moving = (move != Vector3.Zero);
250 #endregion Inputs
251  
252 #region Flying
253  
254 if (actor != null && actor.Flying)
255 {
256 m_animTickFall = 0;
257 m_animTickJump = 0;
258 m_jumping = false;
259 Falling = false;
260 m_jumpVelocity = 0f;
261 actor.Selected = false;
262 m_fallHeight = actor.Position.Z; // save latest flying height
263  
264 if (move.X != 0f || move.Y != 0f)
265 {
266 return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
267 }
268 else if (move.Z > 0f)
269 {
270 return "HOVER_UP";
271 }
272 else if (move.Z < 0f)
273 {
274 if (actor != null && actor.IsColliding)
275 return "LAND";
276 else
277 return "HOVER_DOWN";
278 }
279 else
280 {
281 return "HOVER";
282 }
283 }
284  
285 #endregion Flying
286  
287 #region Falling/Floating/Landing
288  
289 if ((actor == null || !actor.IsColliding) && !m_jumping)
290 {
291 float fallElapsed = (float)(Environment.TickCount - m_animTickFall);
292 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
293  
294 if (!m_jumping && (fallVelocity < -3.0f))
295 Falling = true;
296  
297 if (m_animTickFall == 0 || (fallVelocity >= 0.0f))
298 {
299 // not falling yet, or going up
300 // reset start of fall time
301 m_animTickFall = Environment.TickCount;
302 }
303 else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying))
304 {
305 // Falling long enough to trigger the animation
306 return "FALLDOWN";
307 }
308  
309 // Check if the user has stopped walking just now
310 if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero))
311 return "STAND";
312  
313 return CurrentMovementAnimation;
314 }
315  
316 #endregion Falling/Floating/Landing
317  
318  
319 #region Jumping // section added for jumping...
320  
321 int jumptime;
322 jumptime = Environment.TickCount - m_animTickJump;
323  
324 if ((move.Z > 0f) && (!m_jumping))
325 {
326 // Start jumping, prejump
327 m_animTickFall = 0;
328 m_jumping = true;
329 Falling = false;
330 actor.Selected = true; // borrowed for jumping flag
331 m_animTickJump = Environment.TickCount;
332 m_jumpVelocity = 0.35f;
333 return "PREJUMP";
334 }
335  
336 if (m_jumping)
337 {
338 if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
339 {
340 // end jumping
341 m_jumping = false;
342 Falling = false;
343 actor.Selected = false; // borrowed for jumping flag
344 m_jumpVelocity = 0f;
345 m_animTickFall = Environment.TickCount;
346 return "LAND";
347 }
348 else if (jumptime > JUMP_PERIOD)
349 {
350 // jump down
351 m_jumpVelocity = 0f;
352 return "JUMP";
353 }
354 else if (jumptime > PREJUMP_DELAY)
355 {
356 // jump up
357 m_jumping = true;
358 m_jumpVelocity = 10f;
359 return "JUMP";
360 }
361 }
362  
363 #endregion Jumping
364  
365 #region Ground Movement
366  
367 if (CurrentMovementAnimation == "FALLDOWN")
368 {
369 Falling = false;
370 m_animTickFall = Environment.TickCount;
371 // TODO: SOFT_LAND support
372 float fallHeight = m_fallHeight - actor.Position.Z;
373 if (fallHeight > 15.0f)
374 return "STANDUP";
375 else if (fallHeight > 8.0f)
376 return "SOFT_LAND";
377 else
378 return "LAND";
379 }
380 else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP"))
381 {
382 int landElapsed = Environment.TickCount - m_animTickFall;
383 int limit = 1000;
384 if (CurrentMovementAnimation == "LAND")
385 limit = 350;
386 // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
387  
388 if ((m_animTickFall != 0) && (landElapsed <= limit))
389 {
390 return CurrentMovementAnimation;
391 }
392 else
393 {
394 m_fallHeight = actor.Position.Z; // save latest flying height
395 return "STAND";
396 }
397 }
398  
399 // next section moved outside paren. and realigned for jumping
400 if (move.X != 0f || move.Y != 0f)
401 {
402 m_fallHeight = actor.Position.Z; // save latest flying height
403 Falling = false;
404 // Walking / crouchwalking / running
405 if (move.Z < 0f)
406 {
407 return "CROUCHWALK";
408 }
409 // We need to prevent these animations if the user tries to make their avatar walk or run whilst
410 // specifying AGENT_CONTROL_STOP (pressing down space on viewers).
411 else if (!m_scenePresence.AgentControlStopActive)
412 {
413 if (m_scenePresence.SetAlwaysRun)
414 return "RUN";
415 else
416 return "WALK";
417 }
418 }
419 else if (!m_jumping)
420 {
421 Falling = false;
422 // Not walking
423 if (move.Z < 0)
424 return "CROUCH";
425 else if (heldTurnLeft)
426 return "TURNLEFT";
427 else if (heldTurnRight)
428 return "TURNRIGHT";
429 else
430 return "STAND";
431 }
432 #endregion Ground Movement
433  
434 Falling = false;
435  
436 return CurrentMovementAnimation;
437 }
438  
439 /// <summary>
440 /// Update the movement animation of this avatar according to its current state
441 /// </summary>
442 /// <returns>'true' if the animation was changed</returns>
443 public bool UpdateMovementAnimations()
444 {
445 // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
446  
447 bool ret = false;
448 lock (m_animations)
449 {
450 string newMovementAnimation = DetermineMovementAnimation();
451 if (CurrentMovementAnimation != newMovementAnimation)
452 {
453 CurrentMovementAnimation = DetermineMovementAnimation();
454  
455 // m_log.DebugFormat(
456 // "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
457 // CurrentMovementAnimation, m_scenePresence.Name);
458  
459 // Only set it if it's actually changed, give a script
460 // a chance to stop a default animation
461 ret = TrySetMovementAnimation(CurrentMovementAnimation);
462 }
463 }
464 return ret;
465 }
466  
467 public UUID[] GetAnimationArray()
468 {
469 UUID[] animIDs;
470 int[] sequenceNums;
471 UUID[] objectIDs;
472 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
473 return animIDs;
474 }
475  
476 public BinBVHAnimation GenerateRandomAnimation()
477 {
478 int rnditerations = 3;
479 BinBVHAnimation anim = new BinBVHAnimation();
480 List<string> parts = new List<string>();
481 parts.Add("mPelvis");parts.Add("mHead");parts.Add("mTorso");
482 parts.Add("mHipLeft");parts.Add("mHipRight");parts.Add("mHipLeft");parts.Add("mKneeLeft");
483 parts.Add("mKneeRight");parts.Add("mCollarLeft");parts.Add("mCollarRight");parts.Add("mNeck");
484 parts.Add("mElbowLeft");parts.Add("mElbowRight");parts.Add("mWristLeft");parts.Add("mWristRight");
485 parts.Add("mShoulderLeft");parts.Add("mShoulderRight");parts.Add("mAnkleLeft");parts.Add("mAnkleRight");
486 parts.Add("mEyeRight");parts.Add("mChest");parts.Add("mToeLeft");parts.Add("mToeRight");
487 parts.Add("mFootLeft");parts.Add("mFootRight");parts.Add("mEyeLeft");
488 anim.HandPose = 1;
489 anim.InPoint = 0;
490 anim.OutPoint = (rnditerations * .10f);
491 anim.Priority = 7;
492 anim.Loop = false;
493 anim.Length = (rnditerations * .10f);
494 anim.ExpressionName = "afraid";
495 anim.EaseInTime = 0;
496 anim.EaseOutTime = 0;
497  
498 string[] strjoints = parts.ToArray();
499 anim.Joints = new binBVHJoint[strjoints.Length];
500 for (int j = 0; j < strjoints.Length; j++)
501 {
502 anim.Joints[j] = new binBVHJoint();
503 anim.Joints[j].Name = strjoints[j];
504 anim.Joints[j].Priority = 7;
505 anim.Joints[j].positionkeys = new binBVHJointKey[rnditerations];
506 anim.Joints[j].rotationkeys = new binBVHJointKey[rnditerations];
507 Random rnd = new Random();
508 for (int i = 0; i < rnditerations; i++)
509 {
510 anim.Joints[j].rotationkeys[i] = new binBVHJointKey();
511 anim.Joints[j].rotationkeys[i].time = (i*.10f);
512 anim.Joints[j].rotationkeys[i].key_element.X = ((float) rnd.NextDouble()*2 - 1);
513 anim.Joints[j].rotationkeys[i].key_element.Y = ((float) rnd.NextDouble()*2 - 1);
514 anim.Joints[j].rotationkeys[i].key_element.Z = ((float) rnd.NextDouble()*2 - 1);
515 anim.Joints[j].positionkeys[i] = new binBVHJointKey();
516 anim.Joints[j].positionkeys[i].time = (i*.10f);
517 anim.Joints[j].positionkeys[i].key_element.X = 0;
518 anim.Joints[j].positionkeys[i].key_element.Y = 0;
519 anim.Joints[j].positionkeys[i].key_element.Z = 0;
520 }
521 }
522  
523 AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation, m_scenePresence.UUID.ToString());
524 Animasset.Data = anim.ToBytes();
525 Animasset.Temporary = true;
526 Animasset.Local = true;
527 Animasset.Description = "dance";
528 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data);
529  
530 m_scenePresence.Scene.AssetService.Store(Animasset);
531 AddAnimation(Animasset.FullID, m_scenePresence.UUID);
532 return anim;
533 }
534  
535 /// <summary>
536 ///
537 /// </summary>
538 /// <param name="animations"></param>
539 /// <param name="seqs"></param>
540 /// <param name="objectIDs"></param>
541 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
542 {
543 if (m_scenePresence.IsChildAgent)
544 return;
545  
546 // m_log.DebugFormat(
547 // "[SCENE PRESENCE ANIMATOR]: Sending anim pack with animations '{0}', sequence '{1}', uuids '{2}'",
548 // string.Join(",", Array.ConvertAll<UUID, string>(animations, a => a.ToString())),
549 // string.Join(",", Array.ConvertAll<int, string>(seqs, s => s.ToString())),
550 // string.Join(",", Array.ConvertAll<UUID, string>(objectIDs, o => o.ToString())));
551  
552 m_scenePresence.Scene.ForEachClient(
553 delegate(IClientAPI client)
554 {
555 client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs);
556 });
557 }
558  
559 public void SendAnimPackToClient(IClientAPI client)
560 {
561 if (m_scenePresence.IsChildAgent)
562 return;
563  
564 UUID[] animIDs;
565 int[] sequenceNums;
566 UUID[] objectIDs;
567  
568 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
569 client.SendAnimations(animIDs, sequenceNums, m_scenePresence.ControllingClient.AgentId, objectIDs);
570 }
571  
572 /// <summary>
573 /// Send animation information about this avatar to all clients.
574 /// </summary>
575 public void SendAnimPack()
576 {
577 //m_log.Debug("Sending animation pack to all");
578  
579 if (m_scenePresence.IsChildAgent)
580 return;
581  
582 UUID[] animIDs;
583 int[] sequenceNums;
584 UUID[] objectIDs;
585  
586 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
587  
588 SendAnimPack(animIDs, sequenceNums, objectIDs);
589 }
590  
591 public string GetAnimName(UUID animId)
592 {
593 string animName;
594  
595 if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName))
596 {
597 AssetMetadata amd = m_scenePresence.Scene.AssetService.GetMetadata(animId.ToString());
598 if (amd != null)
599 animName = amd.Name;
600 else
601 animName = "Unknown";
602 }
603  
604 return animName;
605 }
606 }
607 }