public BoneKeyframe GetOrCreateBoneKeyFrame(string boneName, int frame) { Dictionary <int, BoneKeyframe> framesForBone; if (frame > Length) { Length = frame; } if (!BoneMotions.TryGetValue(boneName, out framesForBone)) { framesForBone = new Dictionary <int, BoneKeyframe>(); BoneMotions.Add(boneName, framesForBone); } BoneKeyframe boneKeyframe; if (!framesForBone.TryGetValue(frame, out boneKeyframe)) { boneKeyframe = new BoneKeyframe(); framesForBone.Add(frame, boneKeyframe); } return(boneKeyframe); }
public BonePose GetBonePose(string boneName, int frame) { List <KeyValuePair <int, BoneKeyframe> > keyFrames; BoneMotions.TryGetValue(boneName, out keyFrames); if (keyFrames == null || keyFrames.Count == 0) { return(new BonePose { Translation = Vector3.zero, Rotation = Quaternion.identity }); } if (keyFrames[0].Key >= frame) { var key = keyFrames[0].Value; return(new BonePose { Translation = key.Translation, Rotation = key.Rotation }); } if (keyFrames[keyFrames.Count - 1].Key <= frame) { var key = keyFrames[keyFrames.Count - 1].Value; return(new BonePose { Translation = key.Translation, Rotation = key.Rotation }); } var toSearch = new KeyValuePair <int, BoneKeyframe>(frame, null); var rightBoundIndex = keyFrames.BinarySearch(toSearch, BoneKeyframeSearchComparator.Instance); if (rightBoundIndex < 0) { rightBoundIndex = ~rightBoundIndex; } int leftBoundIndex; if (rightBoundIndex == 0) { leftBoundIndex = 0; } else if (rightBoundIndex >= keyFrames.Count) { rightBoundIndex = leftBoundIndex = keyFrames.Count - 1; } else { leftBoundIndex = rightBoundIndex - 1; } var rightBound = keyFrames[rightBoundIndex]; var rightFrame = rightBound.Key; var rightKey = rightBound.Value; var leftBound = keyFrames[leftBoundIndex]; var leftFrame = leftBound.Key; var leftKey = leftBound.Value; if (leftFrame == rightFrame) { return(new BonePose { Translation = leftKey.Translation, Rotation = leftKey.Rotation }); } var baryPos = (frame - leftFrame) / (float)(rightFrame - leftFrame); var translation = new Vector3(); var lambda = leftKey.XInterpolator.Calculate(baryPos); translation.x = leftKey.Translation.x * (1 - lambda) + rightKey.Translation.x * lambda; lambda = leftKey.YInterpolator.Calculate(baryPos); translation.y = leftKey.Translation.y * (1 - lambda) + rightKey.Translation.y * lambda; lambda = leftKey.ZInterpolator.Calculate(baryPos); translation.z = leftKey.Translation.z * (1 - lambda) + rightKey.Translation.z * lambda; lambda = leftKey.RInterpolator.Calculate(baryPos); var rotation = Quaternion.Lerp(leftKey.Rotation, rightKey.Rotation, lambda); return(new BonePose { Translation = translation, Rotation = rotation }); }