private static void CreateBoneTable(GameSkeleton skeleton, int[] bones, ref AnimationFile animFile) { // Add the bones for (int i = 0; i < bones.Length; i++) { var originalBoneIndex = bones[i]; animFile.Bones[i] = new AnimationFile.BoneInfo() { Id = i, Name = skeleton.BoneNames[originalBoneIndex], ParentId = skeleton.GetParentBone(originalBoneIndex) }; } for (int i = 0; i < bones.Length; i++) { if (animFile.Bones[i].ParentId == -1) { continue; } var parentName = skeleton.BoneNames[animFile.Bones[i].ParentId]; var indexOf = animFile.Bones.Select((value, index) => new { value.Name, index }) .Where(pair => pair.Name == parentName) .Select(pair => pair.index + 1) .FirstOrDefault() - 1; animFile.Bones[i].ParentId = indexOf; } }
public static AnimationFrame Sample(float t, GameSkeleton skeleton, List <AnimationClip> animationClips) { try { var clampedT = EnsureRange(t, 0, 1); int frameIndex = 0; float frameIterpolation = 0; if (animationClips != null) { int maxFrames = animationClips[0].DynamicFrames.Count() - 1; if (maxFrames < 0) { maxFrames = 0; } float frameWithLeftover = maxFrames * clampedT; float clampedFrame = (float)Math.Floor(frameWithLeftover); frameIndex = (int)(clampedFrame); frameIterpolation = frameWithLeftover - clampedFrame; } return(Sample(frameIndex, frameIterpolation, skeleton, animationClips)); } catch (Exception e) { ILogger logger = Logging.Create <AnimationSampler>(); logger.Error(e.Message); throw; } }
public static AnimationFrame Sample(int frameIndex, float frameIterpolation, GameSkeleton skeleton, AnimationClip animationClip) { return(Sample(frameIndex, frameIterpolation, skeleton, new List <AnimationClip>() { animationClip })); }
public Matrix GetSkeletonAnimatedWorldDiff(GameSkeleton gameSkeleton, int boneIndex0, int boneIndex1) { var bone0Transform = GetSkeletonAnimatedWorld(gameSkeleton, boneIndex0); var bone1Transform = GetSkeletonAnimatedWorld(gameSkeleton, boneIndex1); return(bone1Transform * Matrix.Invert(bone0Transform)); }
public void SetAnimation(AnimationClip animation, GameSkeleton skeleton) { if (animation == null) { SetAnimationArray(null, skeleton); } else { SetAnimationArray(new List <AnimationClip>() { animation }, skeleton); } }
public void SetAnimationArray(List <AnimationClip> animation, GameSkeleton skeleton) { if (animation != null) { // Make sure animation fits var numBones = skeleton.BoneCount; var maxAnimBones = Math.Max(animation.Select(x => x.RotationMappings.Count).Max(), animation.Select(x => x.TranslationMappings.Count).Max()); if (maxAnimBones > numBones) { throw new Exception("This animation does not work for this skeleton!"); } } _skeleton = skeleton; _animationClips = animation; _timeSinceStart = TimeSpan.FromSeconds(0); UpdateAnimationFrame(); }
public static AnimationFile ExtractPartOfSkeleton(GameSkeleton skeleton, string skeletonName, int[] bones) { // Header var animFile = new AnimationFile(); animFile.Header.SkeletonName = skeletonName; animFile.Header.AnimationTotalPlayTimeInSec = 0.1f; animFile.Bones = new AnimationFile.BoneInfo[bones.Length]; CreateBoneTable(skeleton, bones, ref animFile); // Create the keyframe animFile.DynamicFrames = new List <AnimationFile.Frame>(); var frame = new AnimationFile.Frame(); animFile.DynamicFrames.Add(frame); // Populate the keyframe for (int i = 0; i < bones.Length; i++) { var originalBoneIndex = bones[i]; if (i == 0) { var worldTrans = skeleton.GetWorldTransform(originalBoneIndex); var res = worldTrans.Decompose(out Vector3 scale, out var rot, out var trans); frame.Transforms.Add(new RmvVector3(trans.X, trans.Y, trans.Z)); frame.Quaternion.Add(new RmvVector4(rot.X, rot.Y, rot.Z, rot.W)); } else { var trans = skeleton.Translation[originalBoneIndex]; var rot = skeleton.Rotation[originalBoneIndex]; frame.Transforms.Add(new RmvVector3(trans.X, trans.Y, trans.Z)); frame.Quaternion.Add(new RmvVector4(rot.X, rot.Y, rot.Z, rot.W)); } } return(animFile); //var sample = AnimationSampler.Sample(0, 0, skeleton, new List<AnimationClip>() { animation }, true, true); }
public static AnimationClip ReSample(GameSkeleton skeleton, AnimationClip newAnim, int newFrameCount, float playTime) { var output = newAnim.Clone(); output.DynamicFrames.Clear(); var fraction = 1.0f / (newFrameCount - 1); for (int i = 0; i < newFrameCount; i++) { float t = i * fraction; var keyframe = AnimationSampler.Sample(t, skeleton, new List <AnimationClip> { newAnim }); KeyFrame newKeyFrame = new KeyFrame(); for (int mappingIndex = 0; mappingIndex < output.RotationMappings.Count; mappingIndex++) { var mapping = output.RotationMappings[mappingIndex]; if (mapping.HasValue) { newKeyFrame.Rotation.Add(keyframe.BoneTransforms[mappingIndex].Rotation); } } for (int mappingIndex = 0; mappingIndex < output.TranslationMappings.Count; mappingIndex++) { var mapping = output.TranslationMappings[mappingIndex]; if (mapping.HasValue) { newKeyFrame.Position.Add(keyframe.BoneTransforms[mappingIndex].Translation); } } output.DynamicFrames.Add(newKeyFrame); } output.PlayTimeInSec = playTime;// (output.DynamicFrames.Count() - 1) / 20.0f; return(output); }
public AnimationFile ConvertToFileFormat(GameSkeleton skeleton) { AnimationFile output = new AnimationFile(); //float frameRate = var fRate = (DynamicFrames.Count() - 1) / PlayTimeInSec; output.Header.FrameRate = (float)Math.Floor(fRate); output.Header.AnimationType = 7; output.Header.AnimationTotalPlayTimeInSec = PlayTimeInSec; output.Header.SkeletonName = skeleton.SkeletonName; output.Bones = new BoneInfo[skeleton.BoneCount]; for (int i = 0; i < skeleton.BoneCount; i++) { output.Bones[i] = new BoneInfo() { Id = i, Name = skeleton.BoneNames[i], ParentId = skeleton.GetParentBone(i) }; } // Mappings output.RotationMappings = RotationMappings.ToList(); output.TranslationMappings = TranslationMappings.ToList(); // Static if (StaticFrame != null) { output.StaticFrame = CreateFrameFromKeyFrame(StaticFrame); } // Dynamic foreach (var frame in DynamicFrames) { output.DynamicFrames.Add(CreateFrameFromKeyFrame(frame)); } return(output); }
public static AnimationFrame Sample(int frameIndex, float frameIterpolation, GameSkeleton skeleton, List <AnimationClip> animationClips) { try { if (skeleton == null) { return(null); } var currentFrame = skeleton.CreateAnimationFrame(); if (animationClips != null) { foreach (var animation in animationClips) { ApplyAnimation(animation.StaticFrame, null, 0, currentFrame, animation.RotationMappings, animation.TranslationMappings, AnimationBoneMappingType.Static); } if (animationClips.Any()) { if (animationClips[0].DynamicFrames.Count > frameIndex) { var currentFrameKeys = GetKeyFrameFromIndex(animationClips[0].DynamicFrames, frameIndex); var nextFrameKeys = GetKeyFrameFromIndex(animationClips[0].DynamicFrames, frameIndex + 1); ApplyAnimation(currentFrameKeys, nextFrameKeys, frameIterpolation, currentFrame, animationClips[0].RotationMappings, animationClips[0].TranslationMappings, AnimationBoneMappingType.Dynamic); // Apply skeleton scale for (int i = 0; i < currentFrame.BoneTransforms.Count(); i++) { currentFrame.BoneTransforms[i].Scale = animationClips[0].DynamicFrames[0].Scale[i]; } } } } for (int i = 0; i < currentFrame.BoneTransforms.Count(); i++) { Quaternion rotation = currentFrame.BoneTransforms[i].Rotation; Vector3 translation = currentFrame.BoneTransforms[i].Translation; currentFrame.BoneTransforms[i].WorldTransform = Matrix.CreateScale(currentFrame.BoneTransforms[i].Scale) * Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(translation); var parentindex = currentFrame.BoneTransforms[i].ParentBoneIndex; if (parentindex == -1) { //var scale = Matrix.CreateScale(0.1f); //currentFrame.BoneTransforms[i].WorldTransform = (scale * currentFrame.BoneTransforms[i].WorldTransform); continue; } currentFrame.BoneTransforms[i].WorldTransform = currentFrame.BoneTransforms[i].WorldTransform * currentFrame.BoneTransforms[parentindex].WorldTransform; } for (int i = 0; i < skeleton.BoneCount; i++) { var inv = Matrix.Invert(skeleton.GetWorldTransform(i)); currentFrame.BoneTransforms[i].WorldTransform = Matrix.Multiply(inv, currentFrame.BoneTransforms[i].WorldTransform); } return(currentFrame); } catch (Exception e) { ILogger logger = Logging.Create <AnimationSampler>(); logger.Error(e.Message); throw; } }
public Matrix GetSkeletonAnimatedWorld(GameSkeleton gameSkeleton, int boneIndex) { Matrix output = gameSkeleton.GetWorldTransform(boneIndex) * BoneTransforms[boneIndex].WorldTransform; return(output); }