private void OnFlipClicked(object sender, System.Windows.RoutedEventArgs e) { if (this.Skeleton != null && !this.IsFlipping) { // if no bone selected, flip both lumbar and waist bones this.IsFlipping = true; if (this.Skeleton.CurrentBone == null) { BoneVisual3d?waistBone = this.Skeleton.GetBone("Waist"); BoneVisual3d?lumbarBone = this.Skeleton.GetBone("SpineA"); this.FlipBone(waistBone); this.FlipBone(lumbarBone); waistBone?.ReadTransform(true); lumbarBone?.ReadTransform(true); } else { // if targeted bone is a limb don't switch the respective left and right sides BoneVisual3d targetBone = this.Skeleton.CurrentBone; if (targetBone.BoneName.EndsWith("Left") || targetBone.BoneName.EndsWith("Right")) { this.FlipBone(targetBone, false); } else { this.FlipBone(targetBone); } targetBone.ReadTransform(true); } this.IsFlipping = false; } }
private static bool IsChildOf(BoneVisual3d childBone, BoneVisual3d parentBone) { if (childBone.Parent == null) { return(false); } if (childBone.Parent == parentBone) { return(true); } return(IsChildOf(childBone.Parent, parentBone)); }
private static async Task ParentBone(SkeletonVisual3d root, IEnumerable <BoneVisual3d> bones, BoneVisual3d bone) { // Must wait for ffxiv to update at least one frame await Task.Delay(75); await Dispatch.MainThread(); // Get the positions of all bones Dictionary <BoneVisual3d, Vector> initialBonePositions = new Dictionary <BoneVisual3d, Vector>(); foreach (BoneVisual3d otherBone in bones) { otherBone.ReadTransform(); initialBonePositions.Add(otherBone, otherBone.Position); } // rotate the test bone Quaternion oldRot = bone.Rotation; bone.Rotation *= Quaternion.FromEuler(new Vector(0, 90, 0)); bone.WriteTransform(root, false); bone.ViewModel.WriteToMemory(true); // Must wait for ffxiv to update at least one frame await Task.Delay(75); await Dispatch.MainThread(); // See if any bones moved as a result of the test bone rotation foreach (BoneVisual3d otherBone in bones) { if (otherBone == bone) { continue; } otherBone.ReadTransform(); // If this bone has moved, then it is a child of the test bone. if (initialBonePositions[otherBone] != otherBone.Position) { //// If this bone is already a child of the testbones hierarchy, dont move it. if (IsChildOf(otherBone, bone)) { continue; } if (IsChildOf(bone, otherBone)) { Log.Warning("Bone that is parent of test bone was moved."); continue; ////throw new Exception("Bone that is parent of test bone was moved."); } otherBone.Parent = bone; } } // Restore the test bone rotation bone.Rotation = oldRot; bone.WriteTransform(root, false); bone.ViewModel.WriteToMemory(true); // restore all initial bone positions foreach (BoneVisual3d otherBone in bones) { otherBone.ReadTransform(); if (initialBonePositions[otherBone] != otherBone.Position) { otherBone.Position = initialBonePositions[otherBone]; otherBone.WriteTransform(root, false); } } }