void OpenBoneRemappingTool() { var targetSkeletonName = _meshNode.MeshModel.ParentSkeletonName; var existingSkeletonMeshNode = _meshNode.GetParentModel(); var existingSkeltonName = existingSkeletonMeshNode.Model.Header.SkeletonName; RemappedAnimatedBoneConfiguration config = new RemappedAnimatedBoneConfiguration(); var existingSkeletonFile = _animLookUp.GetSkeletonFileFromName(_pfs, targetSkeletonName); config.MeshSkeletonName = targetSkeletonName; config.MeshBones = AnimatedBone.CreateFromSkeleton(existingSkeletonFile, AnimatedBones.Select(x => x.BoneIndex).ToList()); var newSkeletonFile = _animLookUp.GetSkeletonFileFromName(_pfs, existingSkeltonName); config.ParnetModelSkeletonName = existingSkeltonName; config.ParentModelBones = AnimatedBone.CreateFromSkeleton(newSkeletonFile); AnimatedBlendIndexRemappingWindow window = new AnimatedBlendIndexRemappingWindow() { DataContext = new AnimatedBlendIndexRemappingViewModel(config) }; if (window.ShowDialog() == true) { var remapping = config.MeshBones.First().BuildRemappingList(); _componentManager.GetComponent <CommandExecutor>().ExecuteCommand(new RemapBoneIndexesCommand(_meshNode, remapping, config.ParnetModelSkeletonName, config.MoveMeshToFit, new GameSkeleton(existingSkeletonFile, null), new GameSkeleton(newSkeletonFile, null))); } }
public static void AutomapDirectBoneLinksBasedOnHierarchy(AnimatedBone boneToGetMapping, AnimatedBone otherBoneToStartFrom) { boneToGetMapping.MappedBoneIndex = otherBoneToStartFrom.BoneIndex; boneToGetMapping.MappedBoneName = otherBoneToStartFrom.Name; for (int i = 0; i < boneToGetMapping.Children.Count(); i++) { if (i < otherBoneToStartFrom.Children.Count()) { AutomapDirectBoneLinksBasedOnHierarchy(boneToGetMapping.Children[i], otherBoneToStartFrom.Children[i]); } } }
public static void ShowView(List <ISelectable> meshesToFit, IComponentManager componentManager, SkeletonAnimationLookUpHelper skeletonHelper, PackFileService pfs) { var sceneManager = componentManager.GetComponent <SceneManager>(); var resourceLib = componentManager.GetComponent <ResourceLibary>(); var animCollection = componentManager.GetComponent <AnimationsContainerComponent>(); var meshNodes = meshesToFit .Where(x => x is Rmv2MeshNode) .Select(x => x as Rmv2MeshNode) .ToList(); var allSkeltonNames = meshNodes .Select(x => x.MeshModel.ParentSkeletonName) .Distinct(); if (allSkeltonNames.Count() != 1) { throw new Exception("Unexpected number of skeletons. This tool only works for one skeleton"); } var currentSkeletonName = allSkeltonNames.First(); var currentSkeletonFile = skeletonHelper.GetSkeletonFileFromName(pfs, currentSkeletonName); var usedBoneIndexes = meshNodes .SelectMany(x => x.Geometry.GetUniqeBlendIndices()) .Distinct() .Select(x => (int)x) .ToList(); var targetSkeleton = componentManager.GetComponent <IEditableMeshResolver>().GeEditableMeshRootNode().Skeleton; var targetSkeletonFile = skeletonHelper.GetSkeletonFileFromName(pfs, targetSkeleton.Name); RemappedAnimatedBoneConfiguration config = new RemappedAnimatedBoneConfiguration(); config.ParnetModelSkeletonName = targetSkeleton.Name; config.ParentModelBones = AnimatedBone.CreateFromSkeleton(targetSkeletonFile); config.MeshSkeletonName = currentSkeletonName; config.MeshBones = AnimatedBone.CreateFromSkeleton(currentSkeletonFile, usedBoneIndexes); var containingWindow = new Window(); containingWindow.Title = "Texture Preview Window"; containingWindow.DataContext = new MeshFitterViewModel(config, meshNodes, targetSkeleton.AnimationProvider.Skeleton, currentSkeletonFile, componentManager); containingWindow.Content = new MeshFitterView(); containingWindow.Closed += ContainingWindow_Closed; containingWindow.Show(); }
public static void AutomapDirectBoneLinksBasedOnNames(AnimatedBone boneToGetMapping, IEnumerable <AnimatedBone> externalBonesList) { var otherBone = FindBoneBasedOnName(boneToGetMapping.Name, externalBonesList); if (otherBone != null) { boneToGetMapping.MappedBoneIndex = otherBone.BoneIndex; boneToGetMapping.MappedBoneName = otherBone.Name; } foreach (var bone in boneToGetMapping.Children) { AutomapDirectBoneLinksBasedOnNames(bone, externalBonesList); } }
public void Update(float elapsedTimeInSeconds) { this.CurrentTime += elapsedTimeInSeconds; // In Seconds if (CurrentTime > AnimationLength) { CurrentTime -= AnimationLength; } if (CurrentTime < 0) { CurrentTime += AnimationLength; } float currentFrame = Fps * CurrentTime; SpuBinary spuBinary = this.mtbSection.FindChild <SpuBinary>(); Dictionary <int, Bone> boneIdMap = new Dictionary <int, Bone>(); for (var i = 0; i < this.Bones.Length; i++) { var thisBone = this.Bones[i]; thisBone.JointMatrixSet = false; AnimatedBoneNode aniBoneNode = spuBinary.FindChild <AnimatedBoneNode>(x => x.Bone.BoneId == thisBone.Id); AnimatedBone aniBone = (aniBoneNode == null) ? null : aniBoneNode.Bone; Vector3 translation; Vector3 scale; Quaternion rotation; translation = skeleton.Bones[i].Translation; scale = skeleton.Bones[i].Scale; rotation = skeleton.Bones[i].Rotation; if (aniBone != null) { translation.X = (aniBone.TranslationX == null) ? skeleton.Bones[i].Translation.X : aniBone.TranslationX.GetValue(currentFrame); translation.Y = (aniBone.TranslationY == null) ? skeleton.Bones[i].Translation.Y : aniBone.TranslationY.GetValue(currentFrame); translation.Z = (aniBone.TranslationZ == null) ? skeleton.Bones[i].Translation.Z : aniBone.TranslationZ.GetValue(currentFrame); scale.X = (aniBone.ScaleX == null) ? skeleton.Bones[i].Scale.X : aniBone.ScaleX.GetValue(currentFrame); scale.Y = (aniBone.ScaleY == null) ? skeleton.Bones[i].Scale.Y : aniBone.ScaleY.GetValue(currentFrame); scale.Z = (aniBone.ScaleZ == null) ? skeleton.Bones[i].Scale.Z : aniBone.ScaleZ.GetValue(currentFrame); if (aniBone.RotationCurve != null) { rotation = aniBone.RotationCurve.GetValue(currentFrame); } } boneIdMap[skeleton.Bones[i].BoneIndex] = thisBone; int parentBoneIndex = skeleton.Bones[i].ParentBoneIndex; if (parentBoneIndex >= 0) { Bone parent = boneIdMap[parentBoneIndex]; // Transform our translation by our parent's rotation quaternion and add to our parent translation Vector4 transformedPos = Vector3.Transform(translation, parent.Orientation); thisBone.Position.X = transformedPos.X + parent.Position.X; thisBone.Position.Y = transformedPos.Y + parent.Position.Y; thisBone.Position.Z = transformedPos.Z + parent.Position.Z; // Rotate our baseframe orientation by our parent joint's rotation quaternion thisBone.Orientation = rotation * parent.Orientation; // Order is important thisBone.Orientation = Quaternion.Normalize(thisBone.Orientation); thisBone.Scale = Vector3.Modulate(scale, parent.Scale); } else { thisBone.Orientation = rotation; thisBone.Position = translation; thisBone.Scale = scale; } } }
public void LoadBones(DatDigger.Sections.Skeleton.SkeletonSection skeleton) { if (IsLoaded) { throw new InvalidOperationException("AnimatedSkeleton already populated"); } this.skeleton = skeleton; this.Bones = new Bone[skeleton.Bones.Count]; Dictionary <int, Bone> boneIdMap = new Dictionary <int, Bone>(); SpuBinary spuBinary = this.mtbSection.FindChild <SpuBinary>(); for (var i = 0; i < this.Bones.Length; i++) { Bone thisBone = new Bone(); thisBone.Id = i; this.Bones[i] = thisBone; AnimatedBoneNode aniBoneNode = spuBinary.FindChild <AnimatedBoneNode>(x => x.Bone.BoneId == i); AnimatedBone aniBone = (aniBoneNode == null) ? null : aniBoneNode.Bone; Vector3 translation; Vector3 scale; Quaternion rotation; if (aniBone != null) { translation = new Vector3(); scale = new Vector3(); translation.X = (aniBone.TranslationX == null) ? skeleton.Bones[i].Translation.X : aniBone.TranslationX.GetValue(0); translation.Y = (aniBone.TranslationY == null) ? skeleton.Bones[i].Translation.Y : aniBone.TranslationY.GetValue(0); translation.Z = (aniBone.TranslationZ == null) ? skeleton.Bones[i].Translation.Z : aniBone.TranslationZ.GetValue(0); scale.X = (aniBone.ScaleX == null) ? skeleton.Bones[i].Scale.X : aniBone.ScaleX.GetValue(0); scale.Y = (aniBone.ScaleY == null) ? skeleton.Bones[i].Scale.Y : aniBone.ScaleY.GetValue(0); scale.Z = (aniBone.ScaleZ == null) ? skeleton.Bones[i].Scale.Z : aniBone.ScaleZ.GetValue(0); rotation = (aniBone.RotationCurve == null) ? skeleton.Bones[i].Rotation : aniBone.RotationCurve.GetValue(0); } else { translation = skeleton.Bones[i].Translation; scale = skeleton.Bones[i].Scale; rotation = skeleton.Bones[i].Rotation; } boneNameMap[skeleton.Bones[i].Name] = thisBone; boneIdMap[skeleton.Bones[i].BoneIndex] = thisBone; int parentBoneIndex = skeleton.Bones[i].ParentBoneIndex; if (parentBoneIndex >= 0) { Bone parent = boneIdMap[parentBoneIndex]; thisBone.ParentId = parent.Id; // Transform our translation by our parent's rotation quaternion and add to our parent translation Vector4 transformedPos = Vector3.Transform(translation, parent.Orientation); thisBone.Position.X = transformedPos.X + parent.Position.X; thisBone.Position.Y = transformedPos.Y + parent.Position.Y; thisBone.Position.Z = transformedPos.Z + parent.Position.Z; // Rotate our baseframe orientation by our parent joint's rotation quaternion thisBone.Orientation = rotation * parent.Orientation; // Order is important thisBone.Orientation = Quaternion.Normalize(thisBone.Orientation); thisBone.Scale = Vector3.Modulate(scale, parent.Scale); } else { thisBone.ParentId = -1; thisBone.Orientation = rotation; thisBone.Position = translation; thisBone.Scale = scale; } } this.IsLoaded = true; }