// @TODO - temporary processing animation context, need to think about where to put this functionality
        public Boolean ProcessAnimationContext(H1AnimationContext animContext)
        {
            H1AnimMontage montage = new H1AnimMontage();

            foreach (H1AnimationContext.AnimSequence animSeq in animContext.AnimSequences)
            {
                String animSeqName = animSeq.AnimSeqName;
                float  duration    = Convert.ToSingle(animSeq.Duration);
                float  tickInSec   = Convert.ToSingle(animSeq.TicksPerSecond);

                // @TODO - temporary insert duration variable
                Duration  = duration;
                TickInSec = tickInSec;

                foreach (H1AnimationContext.JointAnimation jointAnimation in animSeq.BoneAnimations)
                {
                    String boneName = jointAnimation.BoneName;
                    H1SlotAnimationTrack slotAnimationTrack = new H1SlotAnimationTrack();
                    slotAnimationTrack.SlotName     = boneName;
                    slotAnimationTrack.AnimTrackRef = new H1AnimTrack();

                    H1AnimSegment  animSegment  = new H1AnimSegment();
                    H1AnimSequence animSequence = new H1AnimSequence();

                    // 1. process position keys
                    animSequence.TranslationTracks.Add(new H1TranslationTrack());
                    foreach (H1AnimationContext.PositionKey positionKey in jointAnimation.PosKeys)
                    {
                        animSequence.TranslationTracks[0].PosKeys.Add(positionKey.Value);
                        animSequence.TranslationTracks[0].Times.Add(Convert.ToSingle(positionKey.Time));
                    }

                    // 2. process rotation keys
                    animSequence.RotationTracks.Add(new H1RotationTrack());
                    foreach (H1AnimationContext.QuaternionKey quaternionKey in jointAnimation.RotKeys)
                    {
                        animSequence.RotationTracks[0].RotKeys.Add(quaternionKey.Value);
                        animSequence.RotationTracks[0].Times.Add(Convert.ToSingle(quaternionKey.Time));
                    }

                    // 3. process scale keys
                    animSequence.ScaleTracks.Add(new H1ScalingTrack());
                    foreach (H1AnimationContext.ScalingKey scaleKey in jointAnimation.ScaleKeys)
                    {
                        animSequence.ScaleTracks[0].ScaleKeys.Add(scaleKey.Value);
                        animSequence.ScaleTracks[0].Times.Add(Convert.ToSingle(scaleKey.Time));
                    }

                    animSegment.SetAnimSequence(animSequence);
                    slotAnimationTrack.AnimTrackRef.AnimSegments.Add(animSegment);
                    montage.SlotAnimTracks.Add(slotAnimationTrack);
                }
            }

            H1AnimMontageInstance montageInstance = new H1AnimMontageInstance();

            montageInstance.MontageRef = montage;
            m_MontageInstances.Add(montageInstance);

            return(true);
        }
        public Boolean ExtractInterpolatedLocalTransform(float deltaTime, ref List <InterpolatedLocalTransform> localTransforms)
        {
            StopWatch.Stop();
            deltaTime = StopWatch.Elapsed.Milliseconds / 1000.0f;

            //AccumulatedAnimationTime = 0.0f; //deltaTime * 2.0f;
            AccumulatedAnimationTime += 1.0f;

            foreach (InterpolatedLocalTransform interpolatedLocalTransform in localTransforms)
            {
                // find the matched bone name
                H1SlotAnimationTrack slotAnimTrack = m_MontageInstances[0].MontageRef.SlotAnimTracks.Find(
                    x => {
                    return(interpolatedLocalTransform.BoneName == x.SlotName);
                });

                if (slotAnimTrack == null)
                {
                    // skip the current local transform (no modification exists)
                    continue;
                }

                float          accumulatedAnimationTimeInMS = AccumulatedAnimationTime;
                H1AnimSequence animSeq = slotAnimTrack.AnimTrackRef.AnimSegments[0].AnimSequence;

                // invalidate for count mismatched in advance
                if (animSeq.TranslationTracks[0].PosKeys.Count != animSeq.RotationTracks[0].RotKeys.Count ||
                    animSeq.TranslationTracks[0].PosKeys.Count != animSeq.ScaleTracks[0].ScaleKeys.Count)
                {
                    return(false);
                }

                for (Int32 timeSlot = 0; timeSlot < animSeq.TranslationTracks[0].Times.Count; ++timeSlot)
                {
                    float trackTime = animSeq.TranslationTracks[0].Times[timeSlot];
                    if (AccumulatedAnimationTime < trackTime)
                    {
                        Vector3    position = animSeq.TranslationTracks[0].PosKeys[timeSlot];
                        Quaternion rotation = animSeq.RotationTracks[0].RotKeys[timeSlot];
                        Vector3    scale    = animSeq.ScaleTracks[0].ScaleKeys[timeSlot];

                        interpolatedLocalTransform.LocalTransform = new H1Transform()
                        {
                            Translation = position,
                            Rotation    = rotation,
                            Scaling     = scale,
                        };

                        break;
                    }
                }
            }

            if (AccumulatedAnimationTime > Duration)
            {
                AccumulatedAnimationTime -= Duration;
            }

            StopWatch.Start();

            return(true);
        }