Пример #1
0
 /// <summary>
 /// Creates a new joint animation channel
 /// </summary>
 /// <param name="sampler">Sampler</param>
 /// <param name="target">Target Joint</param>
 public JointAnimationChannel(JointAnimationSampler sampler, Joint target)
 {
     _sampler = sampler;
     _target  = target;
 }
Пример #2
0
        /// <summary>
        /// Takes a group of animations which affect the same joint and combines them into
        /// one animation with one channel. For this all transformations of each individual
        /// keyframe are combined. Translations are added, Scales multiplied and rotations
        /// multiplied as well.
        /// </summary>
        /// <param name="animations">List of animations</param>
        /// <returns>Combined animation</returns>
        static JointAnimation CombineAnimations(IEnumerable<JointAnimation> animations)
        {
            if (animations.Count() == 1)
            {
                // If there is only one animation there's no need to join
                return animations.First();
            }

            // Number of frames that have to be combined
            int numFrames = animations.First().NumFrames;

            // All animations must have the same number of frames
            if(!animations.All(a => a.NumFrames == numFrames))
            {
                throw new NotImplementedException("Animations affecting the same joint must " +
                    "have the same number of keyframes");
            }

            var combinedKeyframes = new JointAnimationKeyFrame[numFrames];

            for (int i = 0; i < numFrames; i++)
            {
                // Create a combined key frame
                float time = animations.First().Channels[0].Sampler.Keyframes[i].Time;

                Vector3 scale = new Vector3(1,1,1);
                Quaternion rotation = Quaternion.Identity;
                Vector3 translation = new Vector3(0,0,0);

                foreach (var add in animations.Select(anim => anim.Channels[0].Sampler.Keyframes[i]))
                {
                    if (add.Scale != Vector3.One)
                        scale *= add.Scale;

                    if (add.Translation != Vector3.Zero)
                        translation += add.Translation;

                    // Single axis rotations are executed in order (as defined in the document)
                    // Note: Not sure if this is correct
                    if (add.Rotation != Quaternion.Identity)
                        rotation = add.Rotation * rotation;
                }

                var keyframe = new JointAnimationKeyFrame(time, scale, rotation, translation);
                combinedKeyframes[i] = keyframe;
            }

            Joint target = animations.First().Channels[0].Target;
            var sampler = new JointAnimationSampler(combinedKeyframes, AnimationInterpolation.Linear);

            JointAnimation animation = new JointAnimation(new JointAnimationChannel[]
                                          {
                                              new JointAnimationChannel(sampler, target)
                                          });

            // Names
            if (animations.Any(a => !String.IsNullOrEmpty(a.Name)))
            {
                animation.Name = animations.Where(a => !String.IsNullOrEmpty(a.Name)).
                    Select(a => a.Name).Aggregate((sum, name) => sum + "+" + name);
            }

            if (animations.Any(a => !String.IsNullOrEmpty(a.GlobalID)))
            {
                animation.GlobalID = animations.Where(a => !String.IsNullOrEmpty(a.GlobalID)).
                    Select(a => a.GlobalID).Aggregate((sum, name) => sum + "\n" + name);
            }

            return animation;
        }