OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ScenePresenceAnimator.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.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.PhysicsModules.SharedBase;
39 
40 namespace OpenSim.Region.Framework.Scenes.Animation
41 {
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 
58  public string CurrentMovementAnimation { get; private set; }
59 
60  private int m_animTickFall;
61  private int m_animTickLand;
62  private int m_animTickJump;
63 
64  public bool m_jumping = false;
65 
66  // private int m_landing = 0;
67 
71  public bool Falling { get; private set; }
72 
73  private float m_lastFallVelocity;
74 
79 
81  {
82  m_scenePresence = sp;
83  CurrentMovementAnimation = "CROUCH";
84  }
85 
86  public void AddAnimation(UUID animID, UUID objectID)
87  {
88  if (m_scenePresence.IsChildAgent)
89  return;
90 
91  // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
92  if (m_scenePresence.Scene.DebugAnimations)
93  m_log.DebugFormat(
94  "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}",
95  GetAnimName(animID), animID, m_scenePresence.Name);
96 
97  if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
98  {
99  SendAnimPack();
100  m_scenePresence.TriggerScenePresenceUpdated();
101  }
102  }
103 
104  // Called from scripts
105  public void AddAnimation(string name, UUID objectID)
106  {
107  if (m_scenePresence.IsChildAgent)
108  return;
109 
110  // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
111  // are referenced with lower case names!
112  UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
113  if (animID == UUID.Zero)
114  return;
115 
116  // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
117 
118  AddAnimation(animID, objectID);
119  }
120 
129  public void RemoveAnimation(UUID animID, bool allowNoDefault)
130  {
131  if (m_scenePresence.IsChildAgent)
132  return;
133 
134  if (m_scenePresence.Scene.DebugAnimations)
135  m_log.DebugFormat(
136  "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}",
137  GetAnimName(animID), animID, m_scenePresence.Name);
138 
139  if (m_animations.Remove(animID, allowNoDefault))
140  {
141  SendAnimPack();
142  m_scenePresence.TriggerScenePresenceUpdated();
143  }
144  }
145 
146  public void avnChangeAnim(UUID animID, bool addRemove, bool sendPack)
147  {
148  if (m_scenePresence.IsChildAgent)
149  return;
150 
151  if (animID != UUID.Zero)
152  {
153  if (addRemove)
154  m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero);
155  else
156  m_animations.Remove(animID, false);
157  }
158  if (sendPack)
159  SendAnimPack();
160  }
161 
162  // Called from scripts
163  public void RemoveAnimation(string name)
164  {
165  if (m_scenePresence.IsChildAgent)
166  return;
167 
168  // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
169  // are referenced with lower case names!
170  UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
171  if (animID == UUID.Zero)
172  return;
173 
174  RemoveAnimation(animID, true);
175  }
176 
177  public void ResetAnimations()
178  {
179  if (m_scenePresence.Scene.DebugAnimations)
180  m_log.DebugFormat(
181  "[SCENE PRESENCE ANIMATOR]: Resetting animations for {0} in {1}",
182  m_scenePresence.Name, m_scenePresence.Scene.RegionInfo.RegionName);
183 
184  m_animations.Clear();
185  }
186 
187 
188  UUID aoSitGndAnim = UUID.Zero;
189 
196 
197 
198 
199  public bool TrySetMovementAnimation(string anim)
200  {
201  bool ret = false;
202  if (!m_scenePresence.IsChildAgent)
203  {
204 // m_log.DebugFormat(
205 // "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}",
206 // anim, m_scenePresence.Name);
207 
208  if (aoSitGndAnim != UUID.Zero)
209  {
210  avnChangeAnim(aoSitGndAnim, false, true);
211  aoSitGndAnim = UUID.Zero;
212  }
213 
214  UUID overridenAnim = m_scenePresence.Overrides.GetOverriddenAnimation(anim);
215  if (overridenAnim != UUID.Zero)
216  {
217  if (anim == "SITGROUND")
218  {
219  UUID defsit = DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"];
220  if (defsit == UUID.Zero)
221  return false;
222  m_animations.SetDefaultAnimation(defsit, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
223  aoSitGndAnim = overridenAnim;
224  avnChangeAnim(overridenAnim, true, false);
225  }
226  else
227  {
228  m_animations.SetDefaultAnimation(overridenAnim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
229  }
230  m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION });
231  SendAnimPack();
232  ret = true;
233  }
234  else
235  {
236  // translate sit and sitground state animations
237  if (anim == "SIT" || anim == "SITGROUND")
238  anim = m_scenePresence.sitAnimation;
239 
240  if (m_animations.TrySetDefaultAnimation(
241  anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
242  {
243 // m_log.DebugFormat(
244 // "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
245 // anim, m_scenePresence.Name);
246 
247  // 16384 is CHANGED_ANIMATION
248  m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION });
249  SendAnimPack();
250  ret = true;
251  }
252  }
253  }
254  else
255  {
256  m_log.WarnFormat(
257  "[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}",
258  anim, m_scenePresence.Name);
259  }
260  return ret;
261  }
262 
263  public enum motionControlStates : byte
264  {
265  sitted = 0,
266  flying,
267  falling,
268  jumping,
269  landing,
270  onsurface
271  }
272 
273  public motionControlStates currentControlState = motionControlStates.onsurface;
274 
278  private string DetermineMovementAnimation()
279  {
280  const int FALL_DELAY = 800;
281  const int PREJUMP_DELAY = 200;
282  const int JUMP_PERIOD = 800;
283  #region Inputs
284 
285  if (m_scenePresence.IsInTransit)
286  return CurrentMovementAnimation;
287 
288  if (m_scenePresence.SitGround)
289  {
290  currentControlState = motionControlStates.sitted;
291  return "SITGROUND";
292  }
293  if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero)
294  {
295  currentControlState = motionControlStates.sitted;
296  return "SIT";
297  }
298 
299  AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
300  PhysicsActor actor = m_scenePresence.PhysicsActor;
301 
302  const AgentManager.ControlFlags ANYXYMASK = (
303  AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS |
304  AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG |
305  AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
306  AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG
307  );
308 
309  // Check control flags
310  /* not in use
311  bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0);
312  bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0);
313  bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0);
314  bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0);
315  */
316  bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
317  bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
318  // bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0);
319  // excluded nudge up so it doesn't trigger jump state
320  bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0);
321  bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0);
322  //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
323  //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
324 
325  bool heldOnXY = ((controlFlags & ANYXYMASK) != 0);
326  if (heldOnXY || heldUp || heldDown)
327  {
328  heldTurnLeft = false;
329  heldTurnRight = false;
330  }
331 
332  #endregion Inputs
333 
334  // no physics actor case
335  if (actor == null)
336  {
337  // well what to do?
338 
339  currentControlState = motionControlStates.onsurface;
340  if (heldOnXY)
341  return "WALK";
342 
343  return "STAND";
344  }
345 
346  #region Flying
347 
348  bool isColliding = actor.IsColliding;
349 
350  if (actor.Flying)
351  {
352  m_animTickFall = 0;
353  m_animTickJump = 0;
354  m_jumping = false;
355  Falling = false;
356 
357  currentControlState = motionControlStates.flying;
358 
359  if (heldOnXY)
360  {
361  return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
362  }
363  else if (heldUp)
364  {
365  return "HOVER_UP";
366  }
367  else if (heldDown)
368  {
369  if (isColliding)
370  {
371  actor.Flying = false;
372  currentControlState = motionControlStates.landing;
373  m_animTickLand = Environment.TickCount;
374  return "LAND";
375  }
376  else
377  return "HOVER_DOWN";
378  }
379  else
380  {
381  return "HOVER";
382  }
383  }
384  else
385  {
386  if (isColliding && currentControlState == motionControlStates.flying)
387  {
388  currentControlState = motionControlStates.landing;
389  m_animTickLand = Environment.TickCount;
390  return "LAND";
391  }
392  }
393 
394  #endregion Flying
395 
396  #region Falling/Floating/Landing
397 
398  if (!isColliding && currentControlState != motionControlStates.jumping)
399  {
400  float fallVelocity = actor.Velocity.Z;
401 
402  // if stable on Hover assume falling
403  if(actor.PIDHoverActive && fallVelocity < 0.05f)
404  {
405  Falling = true;
406  currentControlState = motionControlStates.falling;
407  m_lastFallVelocity = fallVelocity;
408  return "FALLDOWN";
409  }
410 
411  if (fallVelocity < -2.5f)
412  Falling = true;
413 
414  if (m_animTickFall == 0 || (fallVelocity >= -0.5f))
415  {
416  m_animTickFall = Environment.TickCount;
417  }
418  else
419  {
420  int fallElapsed = (Environment.TickCount - m_animTickFall);
421  if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f))
422  {
423  currentControlState = motionControlStates.falling;
424  m_lastFallVelocity = fallVelocity;
425  // Falling long enough to trigger the animation
426  return "FALLDOWN";
427  }
428  }
429 
430  // Check if the user has stopped walking just now
431  if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp)
432  return "STAND";
433 
434  return CurrentMovementAnimation;
435  }
436 
437  m_animTickFall = 0;
438 
439  #endregion Falling/Floating/Landing
440 
441  #region Jumping // section added for jumping...
442 
443  if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive)
444  {
445  // Start jumping, prejump
446  currentControlState = motionControlStates.jumping;
447  m_jumping = true;
448  Falling = false;
449  m_animTickJump = Environment.TickCount;
450  return "PREJUMP";
451  }
452 
453  if (currentControlState == motionControlStates.jumping)
454  {
455  int jumptime = Environment.TickCount - m_animTickJump;
456  if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
457  {
458  // end jumping
459  m_jumping = false;
460  Falling = false;
461  actor.Selected = false; // borrowed for jumping flag
462  m_animTickLand = Environment.TickCount;
463  currentControlState = motionControlStates.landing;
464  return "LAND";
465  }
466  else if (jumptime > JUMP_PERIOD)
467  {
468  // jump down
469  return "JUMP";
470  }
471  else if (jumptime > PREJUMP_DELAY)
472  {
473  // jump up
474  m_jumping = true;
475  return "JUMP";
476  }
477  return CurrentMovementAnimation;
478  }
479 
480  #endregion Jumping
481 
482  #region Ground Movement
483 
484  if (currentControlState == motionControlStates.falling)
485  {
486  Falling = false;
487  currentControlState = motionControlStates.landing;
488  m_animTickLand = Environment.TickCount;
489  // TODO: SOFT_LAND support
490  float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
491  if (fallVsq > 300f) // aprox 20*h
492  return "STANDUP";
493  else if (fallVsq > 160f)
494  return "SOFT_LAND";
495  else
496  return "LAND";
497  }
498 
499 
500  if (currentControlState == motionControlStates.landing)
501  {
502  Falling = false;
503  int landElapsed = Environment.TickCount - m_animTickLand;
504  int limit = 1000;
505  if (CurrentMovementAnimation == "LAND")
506  limit = 350;
507  // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
508 
509  if ((m_animTickLand != 0) && (landElapsed <= limit))
510  {
511  return CurrentMovementAnimation;
512  }
513  else
514  {
515  currentControlState = motionControlStates.onsurface;
516  m_animTickLand = 0;
517  return "STAND";
518  }
519  }
520 
521  // next section moved outside paren. and realigned for jumping
522 
523  if (heldOnXY)
524  {
525  currentControlState = motionControlStates.onsurface;
526  Falling = false;
527  // Walking / crouchwalking / running
528  if (heldDown)
529  {
530  return "CROUCHWALK";
531  }
532  // We need to prevent these animations if the user tries to make their avatar walk or run whilst
533  // specifying AGENT_CONTROL_STOP (pressing down space on viewers).
534  else if (!m_scenePresence.AgentControlStopActive)
535  {
536  if (m_scenePresence.SetAlwaysRun)
537  return "RUN";
538  else
539  return "WALK";
540  }
541  }
542  else
543  {
544  currentControlState = motionControlStates.onsurface;
545  Falling = false;
546  // Not walking
547  if (heldDown)
548  return "CROUCH";
549  else if (heldTurnLeft)
550  return "TURNLEFT";
551  else if (heldTurnRight)
552  return "TURNRIGHT";
553  else
554  return "STAND";
555  }
556  #endregion Ground Movement
557 
558  return CurrentMovementAnimation;
559  }
560 
566  {
567  // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
568 
569  bool ret = false;
570  lock (m_animations)
571  {
572  string newMovementAnimation = DetermineMovementAnimation();
573  if (CurrentMovementAnimation != newMovementAnimation)
574  {
575  CurrentMovementAnimation = newMovementAnimation;
576 
577 // m_log.DebugFormat(
578 // "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
579 // CurrentMovementAnimation, m_scenePresence.Name);
580 
581  // Only set it if it's actually changed, give a script
582  // a chance to stop a default animation
583  ret = TrySetMovementAnimation(CurrentMovementAnimation);
584  }
585  }
586  return ret;
587  }
588 
590  {
591  lock (m_animations)
592  {
593  CurrentMovementAnimation = DetermineMovementAnimation();
594  return TrySetMovementAnimation(CurrentMovementAnimation);
595  }
596  }
597 
598  public bool SetMovementAnimations(string motionState)
599  {
600  lock (m_animations)
601  {
602  CurrentMovementAnimation = motionState;
603  return TrySetMovementAnimation(CurrentMovementAnimation);
604  }
605  }
606 
608  {
609  UUID[] animIDs;
610  int[] sequenceNums;
611  UUID[] objectIDs;
612  m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
613  return animIDs;
614  }
615 
617  {
618  int rnditerations = 3;
619  BinBVHAnimation anim = new BinBVHAnimation();
620  List<string> parts = new List<string>();
621  parts.Add("mPelvis"); parts.Add("mHead"); parts.Add("mTorso");
622  parts.Add("mHipLeft"); parts.Add("mHipRight"); parts.Add("mHipLeft"); parts.Add("mKneeLeft");
623  parts.Add("mKneeRight"); parts.Add("mCollarLeft"); parts.Add("mCollarRight"); parts.Add("mNeck");
624  parts.Add("mElbowLeft"); parts.Add("mElbowRight"); parts.Add("mWristLeft"); parts.Add("mWristRight");
625  parts.Add("mShoulderLeft"); parts.Add("mShoulderRight"); parts.Add("mAnkleLeft"); parts.Add("mAnkleRight");
626  parts.Add("mEyeRight"); parts.Add("mChest"); parts.Add("mToeLeft"); parts.Add("mToeRight");
627  parts.Add("mFootLeft"); parts.Add("mFootRight"); parts.Add("mEyeLeft");
628  anim.HandPose = 1;
629  anim.InPoint = 0;
630  anim.OutPoint = (rnditerations * .10f);
631  anim.Priority = 7;
632  anim.Loop = false;
633  anim.Length = (rnditerations * .10f);
634  anim.ExpressionName = "afraid";
635  anim.EaseInTime = 0;
636  anim.EaseOutTime = 0;
637 
638  string[] strjoints = parts.ToArray();
639  anim.Joints = new binBVHJoint[strjoints.Length];
640  for (int j = 0; j < strjoints.Length; j++)
641  {
642  anim.Joints[j] = new binBVHJoint();
643  anim.Joints[j].Name = strjoints[j];
644  anim.Joints[j].Priority = 7;
645  anim.Joints[j].positionkeys = new binBVHJointKey[rnditerations];
646  anim.Joints[j].rotationkeys = new binBVHJointKey[rnditerations];
647  Random rnd = new Random();
648  for (int i = 0; i < rnditerations; i++)
649  {
650  anim.Joints[j].rotationkeys[i] = new binBVHJointKey();
651  anim.Joints[j].rotationkeys[i].time = (i * .10f);
652  anim.Joints[j].rotationkeys[i].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
653  anim.Joints[j].rotationkeys[i].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
654  anim.Joints[j].rotationkeys[i].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
655  anim.Joints[j].positionkeys[i] = new binBVHJointKey();
656  anim.Joints[j].positionkeys[i].time = (i * .10f);
657  anim.Joints[j].positionkeys[i].key_element.X = 0;
658  anim.Joints[j].positionkeys[i].key_element.Y = 0;
659  anim.Joints[j].positionkeys[i].key_element.Z = 0;
660  }
661  }
662 
663  AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation, m_scenePresence.UUID.ToString());
664  Animasset.Data = anim.ToBytes();
665  Animasset.Temporary = true;
666  Animasset.Local = true;
667  Animasset.Description = "dance";
668  //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data);
669 
670  m_scenePresence.Scene.AssetService.Store(Animasset);
671  AddAnimation(Animasset.FullID, m_scenePresence.UUID);
672  return anim;
673  }
674 
681  public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
682  {
683  m_scenePresence.SendAnimPack(animations, seqs, objectIDs);
684  }
685 
686  public void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
687  {
688  animIDs = null;
689  sequenceNums = null;
690  objectIDs = null;
691 
692  if (m_animations != null)
693  m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
694  }
695 
696  public void SendAnimPackToClient(IClientAPI client)
697  {
698  if (m_scenePresence.IsChildAgent)
699  return;
700 
701  UUID[] animIDs;
702  int[] sequenceNums;
703  UUID[] objectIDs;
704 
705  m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
706  client.SendAnimations(animIDs, sequenceNums, m_scenePresence.ControllingClient.AgentId, objectIDs);
707  }
708 
712  public void SendAnimPack()
713  {
714  //m_log.Debug("Sending animation pack to all");
715 
716  if (m_scenePresence.IsChildAgent)
717  return;
718 
719  UUID[] animIDs;
720  int[] sequenceNums;
721  UUID[] objectIDs;
722 
723  m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
724 
725  // SendAnimPack(animIDs, sequenceNums, objectIDs);
726  m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs);
727  }
728 
729  public string GetAnimName(UUID animId)
730  {
731  string animName;
732 
733  if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName))
734  {
735  AssetMetadata amd = m_scenePresence.Scene.AssetService.GetMetadata(animId.ToString());
736  if (amd != null)
737  animName = amd.Name;
738  else
739  animName = "Unknown";
740  }
741 
742  return animName;
743  }
744  }
745 }
void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
Information about an Animation
Definition: Animation.cs:38
bool TrySetMovementAnimation(string anim)
The movement animation is reserved for "main" animations that are mutually exclusive, e.g. flying and sitting.
void avnChangeAnim(UUID animID, bool addRemove, bool sendPack)
Handle all animation duties for a scene presence
void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
Written to decode and encode a binary animation asset. The SecondLife Client reads in a BVH file and ...
void SendAnimPack()
Send animation information about this avatar to all clients.
A Joint and it's associated meta data and keyframes
bool UpdateMovementAnimations()
Update the movement animation of this avatar according to its current state
UUID FullID
Asset UUID
Definition: AssetBase.cs:168
A Joint Keyframe. This is either a position or a rotation.
OpenSim.Region.Framework.Scenes.Animation.AnimationSet AnimationSet
void RemoveAnimation(UUID animID, bool allowNoDefault)
Remove the specified animation