public List <Joint> RasterizeAnimation() { List <Joint> theSkeleton = new List <Joint>(); for (int i = 0; i < Skeleton.Count; i++) { theSkeleton.Add(new Joint()); theSkeleton[i].Sid = Skeleton[i].Sid; } float maximumTimestamp = (float)(Math.Ceiling(Timestamps.Max() * Constants.INSTANCES_PER_SECOND) / Constants.INSTANCES_PER_SECOND); for (float rasterizedCurrentFrame = 0f; rasterizedCurrentFrame <= maximumTimestamp; rasterizedCurrentFrame += 1f / Constants.INSTANCES_PER_SECOND) { float smallerTimestamp = (from timestamp in Timestamps where timestamp <= rasterizedCurrentFrame select timestamp).Max(); float biggerTimestamp = smallerTimestamp; List <float> biggerTimestamps = (from timestamp in Timestamps where timestamp >= rasterizedCurrentFrame select timestamp).ToList(); if (biggerTimestamps.Count > 0) { biggerTimestamp = biggerTimestamps.Min(); } float blend = 0f; if (smallerTimestamp != biggerTimestamp) { blend = (rasterizedCurrentFrame - smallerTimestamp) / (biggerTimestamp - smallerTimestamp); } InterpolateSkeleton(smallerTimestamp, biggerTimestamp, blend); InterpolateSkeletonQuaternions(smallerTimestamp, biggerTimestamp, blend); for (int i = 0; i < Skeleton.Count; i++) { theSkeleton[i].PoseOrigins[rasterizedCurrentFrame] = Skeleton[i].InterpolatedPoseOrigin; theSkeleton[i].PoseQuaternions[rasterizedCurrentFrame] = Skeleton[i].InterpolatedQuaternion; } } latestFrameIndex = Timestamps.Count() - 1; return(theSkeleton); }