示例#1
0
        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns>A copy of this key frame animation.</returns>
        public SkeletonKeyFrameAnimation Clone()
        {
            var clone = new SkeletonKeyFrameAnimation
            {
                EnableInterpolation = EnableInterpolation,
                FillBehavior        = FillBehavior,
                IsAdditive          = IsAdditive,
                TargetObject        = TargetObject,
                TargetProperty      = TargetProperty
            };

            if (IsFrozen)
            {
                // Already frozen.
                for (int i = 0; i < _channels.Length; i++)
                {
                    clone._totalDuration = _totalDuration;
                    clone._times         = _times;
                    clone._channels      = _channels;
                    clone._weights       = new float[_weights.Length];
                    Array.Copy(_weights, clone._weights, _weights.Length);
                    clone._indices       = _indices;
                    clone._keyFrameTypes = _keyFrameTypes;
                    clone._keyFrames     = _keyFrames;
                }
            }
            else
            {
                // Not frozen.

                // Copy key frames.
                if (_preprocessData != null)
                {
                    foreach (var item in _preprocessData.Channels)
                    {
                        int boneIndex = item.Key;
                        var keyFrames = item.Value;
                        foreach (var keyFrame in keyFrames)
                        {
                            clone.AddKeyFrame(boneIndex, keyFrame.Time, keyFrame.Transform);
                        }
                    }

                    // Copy weights.
                    foreach (var item in _preprocessData.Weights)
                    {
                        clone.SetWeight(item.Key, item.Value);
                    }
                }
            }

            return(clone);
        }
        protected override void LoadContent()
        {
            _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;

              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPoseUncompressed = SkeletonPose.Create(skeleton);
              _skeletonPoseCompressed = SkeletonPose.Create(skeleton);

              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              _animation = animations.Values.First();

              RestartAnimations();

              base.LoadContent();
        }
示例#3
0
    public CompressionSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude");
      SampleHelper.EnablePerPixelLighting(modelNode);

      _meshNodeUncompressed = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _meshNodeUncompressed.PoseLocal = new Pose(new Vector3F(-0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      GraphicsScreen.Scene.Children.Add(_meshNodeUncompressed);

      _meshNodeCompressed = _meshNodeUncompressed.Clone();
      _meshNodeCompressed.PoseLocal = new Pose(new Vector3F(0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      GraphicsScreen.Scene.Children.Add(_meshNodeCompressed);

      Dictionary<string, SkeletonKeyFrameAnimation> animations = _meshNodeUncompressed.Mesh.Animations;
      _animation = animations.Values.First();
      
      RestartAnimations();
    }
        /// <summary>
        /// Converts an AnimationContent to a SkeletonKeyFrameAnimation.
        /// </summary>
        private SkeletonKeyFrameAnimation ProcessAnimation(AnimationContent animationContent, Skeleton skeleton, ContentProcessorContext context)
        {
            var animation = new SkeletonKeyFrameAnimation { EnableInterpolation = true };

              // Process all animation channels (each channel animates a bone).
              int numberOfKeyFrames = 0;
              foreach (var item in animationContent.Channels)
              {
            string channelName = item.Key;
            AnimationChannel channel = item.Value;

            int boneIndex = skeleton.GetIndex(channelName);
            if (boneIndex == -1)
            {
              var message = string.Format("Found animation for bone '{0}', which is not part of the skeleton.", channelName);
              throw new InvalidContentException(message, animationContent.Identity);
            }

            var bindPoseRelativeInverse = skeleton.GetBindPoseRelative(boneIndex).Inverse;
            foreach (AnimationKeyframe keyframe in channel)
            {
              TimeSpan time = keyframe.Time;
              SrtTransform transform = SrtTransform.FromMatrix(keyframe.Transform);

              // The matrix in the key frame is the transformation in the coordinate space of the
              // parent bone. --> Convert it to a transformation relative to the animated bone.
              transform = bindPoseRelativeInverse * transform;

              // To start with minimal numerical errors, we normalize the rotation quaternion.
              transform.Rotation.Normalize();

              animation.AddKeyFrame(boneIndex, time, transform);
              numberOfKeyFrames++;
            }
              }

              if (numberOfKeyFrames == 0)
            throw new InvalidContentException("Animation has no keyframes.", animationContent.Identity);

             // Compress animation to safe memory.
              float removedKeyFrames = animation.Compress(
            CompressionScaleThreshold,
            CompressionRotationThreshold,
            CompressionTranslationThreshold);

              if (removedKeyFrames > 0)
            context.Logger.LogImportantMessage("{0}: Compression removed {1:P} of all key frames.",
                                           animationContent.Name,
                                           removedKeyFrames);

              // Finalize the animation. (Optimizes the animation data for fast runtime access.)
              animation.Freeze();

              return animation;
        }
示例#5
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,
      };
    }
        private SkeletonKeyFrameAnimation BuildAnimation(AnimationContent animationContent)
        {
            string name = animationContent.Name;

              // Add loop frame?
              bool addLoopFrame = false;
              if (_modelDescription != null)
              {
            var animationDescription = _modelDescription.Animation;
            if (animationDescription != null)
            {
              addLoopFrame = animationDescription.AddLoopFrame ?? false;

              if (animationDescription.Splits != null)
              {
            foreach (var split in animationDescription.Splits)
            {
              if (split.Name == name)
              {
                if (split.AddLoopFrame.HasValue)
                  addLoopFrame = split.AddLoopFrame.Value;

                break;
              }
            }
              }
            }
              }

              var animation = new SkeletonKeyFrameAnimation { EnableInterpolation = true };

              // Process all animation channels (each channel animates a bone).
              int numberOfKeyFrames = 0;
              foreach (var item in animationContent.Channels)
              {
            string channelName = item.Key;
            AnimationChannel channel = item.Value;

            int boneIndex = _skeleton.GetIndex(channelName);
            if (boneIndex != -1)
            {
              SrtTransform? loopFrame = null;

              var bindPoseRelativeInverse = _skeleton.GetBindPoseRelative(boneIndex).Inverse;
              foreach (AnimationKeyframe keyframe in channel)
              {
            TimeSpan time = keyframe.Time;
            SrtTransform transform = SrtTransform.FromMatrix(keyframe.Transform);

            // The matrix in the key frame is the transformation in the coordinate space of the
            // parent bone. --> Convert it to a transformation relative to the animated bone.
            transform = bindPoseRelativeInverse * transform;

            // To start with minimal numerical errors, we normalize the rotation quaternion.
            transform.Rotation.Normalize();

            if (loopFrame == null)
              loopFrame = transform;

            if (!addLoopFrame || time < animationContent.Duration)
              animation.AddKeyFrame(boneIndex, time, transform);

            numberOfKeyFrames++;
              }

              if (addLoopFrame && loopFrame.HasValue)
            animation.AddKeyFrame(boneIndex, animationContent.Duration, loopFrame.Value);
            }
            else
            {
              _context.Logger.LogWarning(
            null, animationContent.Identity,
            "Found animation for bone \"{0}\", which is not part of the skeleton.",
            channelName);
            }
              }

              if (numberOfKeyFrames == 0)
              {
            _context.Logger.LogWarning(null, animationContent.Identity, "Animation is ignored because it has no keyframes.");
            return null;
              }

              // Compress animation to save memory.
              if (_modelDescription != null)
              {
            var animationDescription = _modelDescription.Animation;
            if (animationDescription != null)
            {
              float removedKeyFrames = animation.Compress(
            animationDescription.ScaleCompression,
            animationDescription.RotationCompression,
            animationDescription.TranslationCompression);

              if (removedKeyFrames > 0)
              {
            _context.Logger.LogImportantMessage("{0}: Compression removed {1:P} of all key frames.",
                                                string.IsNullOrEmpty(name) ? "Unnamed" : name,
                                                removedKeyFrames);
              }
            }
              }

              // Finalize the animation. (Optimizes the animation data for fast runtime access.)
              animation.Freeze();

              return animation;
        }