示例#1
0
        protected virtual int ReduceKeyframes(Keyframe[] frames, float tolerance)
        {
#if DEBUG
            if (frames == null)
            {
                throw new ArgumentNullException("frames");
            }
#endif
            int      nReduced  = 0;
            Keyframe lerp      = new Keyframe();
            int      nFrames   = frames.Length;
            int      prevFrame = 0;
            Keyframe prevData  = frames[0];
            for (int curFrame = 1; curFrame < nFrames - 1; ++curFrame)
            {
                Keyframe curData   = frames[curFrame];
                int      nextFrame = curFrame + 1;
                Keyframe nextData  = frames[nextFrame];
                Keyframe.Interpolate(prevData, nextData,
                                     (float)(curFrame - prevFrame) / (float)(nextFrame - prevFrame),
                                     lerp);
                if (lerp.DifferenceFrom(curData) < tolerance)
                {
                    frames[curFrame] = null;
                    ++nReduced;
                }
                else
                {
                    prevFrame = curFrame;
                    prevData  = curData;
                }
            }
            return(nReduced);
        }
示例#2
0
        /// <summary>
        /// SampleChannel will be called to sample the transformation of a given channel
        /// at a given time. The given index parameter is for use by the sample function,
        /// to avoid having to look for the "base" frame each call. It will start out as
        /// zero in the first call for a given channel. "time" will be monotonically
        /// increasing for a given channel.
        /// </summary>
        /// <param name="achan">The channel to sample from.</param>
        /// <param name="time">The time to sample at (monotonically increasing).</param>
        /// <param name="ix">For use by SampleChannel (starts at 0 for each new channel).</param>
        /// <returns>The sampled keyframe output (allocated by this function).</returns>
        protected virtual Keyframe SampleChannel(AnimationChannel achan, float time, ref int ix)
        {
            Keyframe          ret   = new Keyframe();
            AnimationKeyframe akf0  = achan[ix];
            float             scale = CalcTransformScale(akf0.Transform);
            //todo:  really should be done in world space, but I'm giving up now
            float offset = akf0.Transform.Translation.Length();

            if (scale > maxScale_)
            {
                maxScale_ = scale;
            }
            if (offset > maxOffset_)
            {
                maxOffset_ = offset;
            }
again:
            if (ix == achan.Count - 1)
            {
                return(KeyframeFromMatrix(akf0.Transform, ret));
            }
            AnimationKeyframe akf1 = achan[ix + 1];

            if (akf1.Time.TotalSeconds <= time)
            {
                akf0 = akf1;
                ++ix;
                goto again;
            }
            KeyframeFromMatrix(akf0.Transform, tmpA_);
            KeyframeFromMatrix(akf1.Transform, tmpB_);
            Keyframe.Interpolate(tmpA_, tmpB_,
                                 (float)((time - akf0.Time.TotalSeconds) / (akf1.Time.TotalSeconds - akf0.Time.TotalSeconds)),
                                 ret);
            return(ret);
        }