Beispiel #1
0
 public void Draw(IList<Matrix> bones, AvatarExpression expression)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Updates the expression with the correct keyframes based on the current time.
        /// </summary>
        /// <param name="playingForward">
        /// If true, the animation is playing forward; otherwise, it is playing backwards
        /// </param>
        private void UpdateAvatarExpression(bool playingForward)
        {
            // Check to see if we have an expression animation
            if (ExpressionKeyframes == null || ExpressionKeyframes.Count == 0)
                return;

            if (playingForward)
            {
                while (currentExpressionKeyframe < ExpressionKeyframes.Count)
                {
                    // Get the current keyframe
                    AvatarExpressionKeyFrame keyframe = ExpressionKeyframes[currentExpressionKeyframe];

                    // Stop when we've read up to the current time.
                    if (keyframe.Time >= currentPosition)
                        break;

                    // Set the current expression
                    avatarExpression = keyframe.Expression;

                    // Move the current keyframe forward.
                    currentExpressionKeyframe++;
                }
            }
            else
            {
                while (currentExpressionKeyframe >= 0)
                {
                    // Get the current keyframe
                    AvatarExpressionKeyFrame keyframe = ExpressionKeyframes[currentExpressionKeyframe];

                    // Stop when we've read back to the current time.
                    if (keyframe.Time <= currentPosition)
                        break;

                    // Set the current expression
                    avatarExpression = keyframe.Expression;

                    // Move the current keyframe backwards.
                    currentExpressionKeyframe--;
                }
            }
        }
Beispiel #3
0
 public void Draw(IList <Matrix> bones, AvatarExpression expression)
 {
     throw new NotImplementedException();
 }
Beispiel #4
0
    private ITimeline BakeAnimation(AvatarAnimation avatarAnimation)
    {
      // Create an AvatarExpression key frame animation that will be applied to the Expression
      // property of an AvatarPose.
      AvatarExpressionKeyFrameAnimation expressionAnimation = new AvatarExpressionKeyFrameAnimation
      {
        TargetProperty = "Expression"
      };

      // Create a SkeletonPose key frame animation that will be applied to the SkeletonPose
      // property of an AvatarPose.
      SkeletonKeyFrameAnimation skeletonKeyFrameAnimation = new SkeletonKeyFrameAnimation
      {
        TargetProperty = "SkeletonPose"
      };

      // In the next loop, we sample the original animation with 30 Hz and store the key frames.
      int numberOfKeyFrames = 0;
      AvatarExpression previousExpression = new AvatarExpression();
      TimeSpan time = TimeSpan.Zero;
      TimeSpan length = avatarAnimation.Length;
      TimeSpan step = new TimeSpan(333333); //  1/30 seconds;
      while (true)
      {
        // Advance time in AvatarAnimation.
        avatarAnimation.CurrentPosition = time;

        // Add expression key frame if this is the first key frame or if the key frame is 
        // different from the last key frame.
        AvatarExpression expression = avatarAnimation.Expression;
        if (time == TimeSpan.Zero || !expression.Equals(previousExpression))
          expressionAnimation.KeyFrames.Add(new KeyFrame<AvatarExpression>(time, expression));

        previousExpression = expression;

        // Convert bone transforms to SrtTransforms and add key frames to the SkeletonPose
        // animation.
        for (int i = 0; i < avatarAnimation.BoneTransforms.Count; i++)
        {
          SrtTransform boneTransform = SrtTransform.FromMatrix(avatarAnimation.BoneTransforms[i]);
          skeletonKeyFrameAnimation.AddKeyFrame(i, time, boneTransform);
          numberOfKeyFrames++;
        }

        // Abort if we have arrived at the end time.
        if (time == length)
          break;

        // Increase time. We check that we do not step over the end time. 
        if (time + step > length)
          time = length;
        else
          time += step;
      }

      // Compress animation to save memory.
      float numberOfRemovedKeyFrames = skeletonKeyFrameAnimation.Compress(0.1f, 0.1f, 0.001f);
      Debug.WriteLine("Compression removed " + numberOfRemovedKeyFrames * 100 + "% of the key frames.");

      // Finalize the skeleton key frame animation. This optimizes the internal data structures.
      skeletonKeyFrameAnimation.Freeze();

      return new TimelineGroup
      {
        expressionAnimation,
        skeletonKeyFrameAnimation,
      };
    }
        /// <summary>
        /// Constructs a new CustomAvatarAnimationPlayer object.
        /// </summary>
        /// <param name="name">The name of the animation.</param>
        /// <param name="length">The length of the animation.</param>
        /// <param name="keyframes">The keyframes in the animation.</param>
        public CustomAvatarAnimation(string name, TimeSpan length,
            List<AvatarKeyFrame> keyframes)
            : base(name, length, keyframes)
        {
            // Reset the current bone transforms
            for (int i = 0; i < AvatarRenderer.BoneCount; i++)
                avatarBoneTransforms[i] = Matrix.Identity;

            BoneTransforms = new ReadOnlyCollection<Matrix>( avatarBoneTransforms );

            Expression = new AvatarExpression();

            // Update the current bone transforms to the first position in the animation
            Update(TimeSpan.Zero, false);
        }
		/// <summary></summary>
		protected override void OnEndProcessAnimation()
		{
			Matrix identity = Matrix.Identity;

			overrideExpression = false;
			expression = new Microsoft.Xna.Framework.GamerServices.AvatarExpression();

			foreach (AnimationStreamControl animation in this.animations)
			{
				AvatarAnimationStreamControl anim = animation as AvatarAnimationStreamControl;
				if (anim != null)
				{
					overrideExpression |= anim.GetExpression(ref expression);

					float weight = anim.WeightedScale;

					if (weight == 0)
						continue;

					Matrix matrix;

					if (weight == 1)
					{
						//mult the bone matrices...

						for (int i = 0; i < this.boneList.Length; i++)
						{
							matrix = anim.BoneTransforms[i];
							Transform transform = new Transform(ref matrix);

							Transform.Multiply(ref this.transformedBones[i], ref transform, out this.transformedBones[i]);
						}
					}
					else
					{
						for (int i = 0; i < this.boneList.Length; i++)
						{
							//matrices are annoying to lerp...
							//so.. use a transform.
							matrix = anim.BoneTransforms[i];
							Transform transform = new Transform(ref matrix);
							transform.InterpolateToIdentity(weight);

							Transform.Multiply(ref this.transformedBones[i], ref transform, out this.transformedBones[i]);
						}
					}
				}
			}


			if (this.parent.sourceData != null && boneModifierBuffer != null)
			{
				boneModifierBuffer.ProcessAvatarBones(this.transformedBones, parent.sourceData,
					new ReadOnlyArrayCollection<Transform>(parent.bindPoseWorld),
					new ReadOnlyArrayCollection<Transform>(parent.bindPoseWorldInverse));
			}

			for (int i = 0; i < this.transformedBones.Length; i++)
			{
				this.transformedBones[i].GetMatrix(out this.boneList[i]);
			}

			if (this.parent.sourceData != null && boneModifierBuffer != null &&
				boneModifierBuffer.CallProcessReadonlyHierarchyTransformedBones)
			{
				this.parent.sourceData.skeleton.TransformHierarchy(this.transformedBones);

				boneModifierBuffer.ProcessReadonlyHierarchyTransformedBones(this.transformedBones, parent.sourceData,
					new ReadOnlyArrayCollection<Transform>(parent.bindPoseWorld),
					new ReadOnlyArrayCollection<Transform>(parent.bindPoseWorldInverse));
			}

		}
		internal bool GetExpressionOverride(ref Microsoft.Xna.Framework.GamerServices.AvatarExpression expression)
		{
			if (overrideExpression)
				expression = this.expression;
			return overrideExpression;
		}
 /// <summary>
 /// Constructs a new AvatarExpressionKeyFrame object.
 /// </summary>
 public AvatarExpressionKeyFrame(TimeSpan time, AvatarExpression expression)
 {
     Time = time;
     Expression = expression;
 }