示例#1
0
            public BckANK1(UInt32 size, Stream stream)
            {
                long secptr = stream.Position - 8;//section pointer

                this.magic = "ANK1";
                this.size  = size;

                hdr = Header.Read(stream);                                        //get header

                stream.Seek(secptr + hdr.jointanimationoffset, SeekOrigin.Begin); //go to the animations
                for (int i = 0; i < hdr.jointanimationcount; i++)
                {
                    jointanims.Add(JointAnimation.Read(stream));         //read animations
                }
                stream.Seek(secptr + hdr.scaleoffset, SeekOrigin.Begin); //go to the scales
                for (int i = 0; i < hdr.scalecount; i++)
                {
                    scales.Add(Data.ReadSingle(stream));               //read scales
                }
                stream.Seek(secptr + hdr.rotoffset, SeekOrigin.Begin); //go to rotations
                for (int i = 0; i < hdr.rotcount; i++)
                {
                    rotations.Add(Data.ReadInt16(stream));                     //read rotations
                }
                stream.Seek(secptr + hdr.translationoffset, SeekOrigin.Begin); //go to translations
                for (int i = 0; i < hdr.translationcount; i++)
                {
                    translations.Add(Data.ReadSingle(stream));                         //read translations
                }
                anglescale = (float)Math.Pow(2f, hdr.anglescaleexp) * (180f / 32767f); //some kind of float shenanigans

                stream.Seek(secptr + this.size, SeekOrigin.Begin);                     //seek the next section
            }
示例#2
0
                public static JointAnimation Read(Stream str)
                {
                    JointAnimation anim = new JointAnimation();

                    anim.x = ComponentAnimation.Read(str);
                    anim.y = ComponentAnimation.Read(str);
                    anim.z = ComponentAnimation.Read(str);
                    return(anim);
                }
示例#3
0
        static JointAnimation ImportAnimation(XmlNode xmlAnimation, Dictionary <string, Joint> joints)
        {
            XmlNodeList xmlChannels = xmlAnimation.SelectNodes("//channel");
            List <JointAnimationChannel> channels = new List <JointAnimationChannel>();

            foreach (XmlNode xmlChannel in xmlChannels)
            {
                // Target joint
                string target  = xmlChannel.Attributes["target"].Value;
                string jointId = ExtractNodeIdFromTarget(target);
                if (!joints.ContainsKey(jointId))
                {
                    continue;
                    //throw new ApplicationException("Animated Joint '" + jointId + "' not found");
                }

                Joint joint = joints[jointId];

                // Sampler
                string  samplerId  = xmlChannel.Attributes["source"].Value.Substring(1);
                XmlNode xmlSampler = xmlAnimation.SelectSingleNode("//sampler[@id='" + samplerId + "']");
                if (xmlSampler == null)
                {
                    throw new ApplicationException("Animation Sampler '" + samplerId + "' not found");
                }

                var sampler = ImportSampler(xmlAnimation, xmlSampler, target);

                channels.Add(new JointAnimationChannel(sampler, joint));
            }

            JointAnimation animation = new JointAnimation(channels.ToArray());

            if (xmlAnimation.Attributes["id"] != null)
            {
                animation.GlobalID = xmlAnimation.Attributes["id"].Value;
            }

            if (xmlAnimation.Attributes["name"] != null)
            {
                animation.Name = xmlAnimation.Attributes["name"].Value;
            }

            if (xmlAnimation.Attributes["sid"] != null)
            {
                animation.ScopedID = xmlAnimation.Attributes["sid"].Value;
            }

            return(animation);
        }
示例#4
0
        /// <summary>
        /// Takes a list of animations each having one channel with a distinct target
        /// and creates a single animation of them by storing all channels of the
        /// input animations in one resulting animation instance.
        /// </summary>
        /// <remarks>This is necessary because some DCC tools split one "real" animation
        /// up into several animation tags in the collada file.</remarks>
        /// <param name="animations">List of animations</param>
        /// <returns>Merged Animation</returns>
        static JointAnimation MergeAnimations(IEnumerable <JointAnimation> animations)
        {
            JointAnimation animation = null;

            if ((from a in animations select a.Channels[0].Target).Distinct().Count() != animations.Count() ||
                (from a in animations select a.Channels.Length).Max() > 1)
            {
                throw new Exception("Only animations with one channel each targetting distinct joints can be merged");
            }

            var channels = (from a in animations select a.Channels[0]).ToArray();

            animation = new JointAnimation(channels);

            return(animation);
        }
示例#5
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);
        }
示例#6
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;
        }
示例#7
0
        /// <summary>
        /// Takes a list of animations each having one channel with a distinct target
        /// and creates a single animation of them by storing all channels of the
        /// input animations in one resulting animation instance.
        /// </summary>
        /// <remarks>This is necessary because some DCC tools split one "real" animation
        /// up into several animation tags in the collada file.</remarks>
        /// <param name="animations">List of animations</param>
        /// <returns>Merged Animation</returns>
        static JointAnimation MergeAnimations(IEnumerable<JointAnimation> animations)
        {
            JointAnimation animation = null;

            if ((from a in animations select a.Channels[0].Target).Distinct().Count() != animations.Count() ||
                (from a in animations select a.Channels.Length).Max() > 1)
            {
                throw new Exception("Only animations with one channel each targetting distinct joints can be merged");
            }

            var channels = (from a in animations select a.Channels[0]).ToArray();

            animation = new JointAnimation(channels);

            return animation;
        }
示例#8
0
        static JointAnimation ImportAnimation(XmlNode xmlAnimation, Dictionary<string,Joint> joints)
        {
            XmlNodeList xmlChannels = xmlAnimation.SelectNodes("//channel");
            List<JointAnimationChannel> channels = new List<JointAnimationChannel>();

            foreach (XmlNode xmlChannel in xmlChannels)
            {
                // Target joint
                string target = xmlChannel.Attributes["target"].Value;
                string jointId = ExtractNodeIdFromTarget(target);
                if (!joints.ContainsKey(jointId))
                {
                    continue;
                    //throw new ApplicationException("Animated Joint '" + jointId + "' not found");
                }

                Joint joint = joints[jointId];

                // Sampler
                string samplerId = xmlChannel.Attributes["source"].Value.Substring(1);
                XmlNode xmlSampler = xmlAnimation.SelectSingleNode("//sampler[@id='" + samplerId + "']");
                if (xmlSampler == null)
                    throw new ApplicationException("Animation Sampler '" + samplerId + "' not found");

                var sampler = ImportSampler(xmlAnimation, xmlSampler, target);

                channels.Add(new JointAnimationChannel(sampler, joint));
            }

            JointAnimation animation = new JointAnimation(channels.ToArray());

            if (xmlAnimation.Attributes["id"] != null)
                animation.GlobalID = xmlAnimation.Attributes["id"].Value;

            if (xmlAnimation.Attributes["name"] != null)
                animation.Name = xmlAnimation.Attributes["name"].Value;

            if (xmlAnimation.Attributes["sid"] != null)
                animation.ScopedID = xmlAnimation.Attributes["sid"].Value;

            return animation;
        }