示例#1
0
        public void WriteToFile(ActorViewModel actor, SkeletonVisual3d skeleton, Configuration config)
        {
            this.Config = config;

            ////SkeletonViewModel? skeletonMem = actor?.ModelObject?.Skeleton?.Skeleton;

            if (skeleton == null || skeleton.Bones == null)
            {
                throw new Exception("No skeleton in actor");
            }

            this.Bones = new Dictionary <string, Bone?>();

            foreach (BoneVisual3d bone in skeleton.Bones)
            {
                if (config.UseSelection && !skeleton.GetIsBoneSelected(bone))
                {
                    continue;
                }

                Transform?trans = bone.ViewModel.Model;

                if (trans == null)
                {
                    throw new Exception("Bone is missing transform");
                }

                this.Bones.Add(bone.BoneName, new Bone(trans.Value));
            }
        }
示例#2
0
            public void FromActor(ActorViewModel actor, SkeletonVisual3d skeleton, Vector rootPos, Configuration config)
            {
                if (actor.ModelObject?.Transform != null)
                {
                    if (config.IncludeActorPosition)
                    {
                        this.Position = rootPos - actor.ModelObject.Transform.Position;
                    }

                    if (config.IncludeActorRotation)
                    {
                        this.Rotation = actor.ModelObject.Transform.Rotation;
                    }

                    if (config.IncludeActorScale)
                    {
                        this.Scale = actor.ModelObject.Transform.Scale;
                    }
                }

                this.Pose = new PoseFile();
                this.Pose.WriteToFile(actor, skeleton, config.Pose);

                this.Character = new CharacterFile();
                this.Character.WriteToFile(actor, config.Character);
            }
示例#3
0
        public static async Task ParentBones(SkeletonVisual3d root, IEnumerable <BoneVisual3d> bones)
        {
            PoseService.Instance.IsEnabled       = true;
            PoseService.Instance.EnableParenting = false;

            try
            {
                foreach (BoneVisual3d bone in bones)
                {
                    root.Children.Add(bone);
                    bone.ReadTransform();
                }

                foreach (BoneVisual3d bone in bones)
                {
                    await ParentBone(root, bones, bone);
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                PoseService.Instance.IsEnabled = false;
            }
        }
示例#4
0
        private async void ExportPose(TargetService.ActorTableActor actor)
        {
            ActorViewModel?actorVm = actor.GetViewModel();

            if (actorVm == null)
            {
                return;
            }

            SkeletonVisual3d skeletonVm = await PoseService.GetVisual(actorVm);

            await PoseFile.Save(actorVm, skeletonVm);
        }
示例#5
0
        private void OnGroupClicked(object sender, System.Windows.RoutedEventArgs e)
        {
            if (sender is DependencyObject ob)
            {
                GroupBox?groupBox = ob.FindParent <GroupBox>();
                if (groupBox == null)
                {
                    return;
                }

                SkeletonVisual3d skeleton = (SkeletonVisual3d)this.DataContext;

                if (!Keyboard.IsKeyDown(Key.LeftCtrl))
                {
                    skeleton.SelectedBones.Clear();
                }

                List <BoneView> bones = groupBox.FindChildren <BoneView>();
                skeleton.Select(bones);
            }
        }
示例#6
0
        public async Task Apply(ActorViewModel actor, SkeletonVisual3d skeleton, Configuration config)
        {
            if (actor == null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (actor.ModelObject == null)
            {
                throw new Exception("Actor has no model");
            }

            if (actor.ModelObject.Skeleton == null)
            {
                throw new Exception("Actor model has no skeleton wrapper");
            }

            if (actor.ModelObject.Skeleton.Skeleton == null)
            {
                throw new Exception("Actor skeleton wrapper has no skeleton");
            }

            SkeletonViewModel skeletonMem = actor.ModelObject.Skeleton.Skeleton;

            skeletonMem.MemoryMode = MemoryModes.None;

            PoseService.Instance.SetEnabled(true);
            PoseService.Instance.CanEdit = false;
            await Task.Delay(100);

            if (this.Bones != null)
            {
                // Apply all transforms a few times to ensure parent-inherited values are caluclated correctly, and to ensure
                // we dont end up with some values read during a ffxiv frame update.
                for (int i = 0; i < 3; i++)
                {
                    foreach ((string name, Bone? savedBone) in this.Bones)
                    {
                        if (savedBone == null)
                        {
                            continue;
                        }

                        BoneVisual3d?bone = skeleton.GetBone(name);

                        if (bone == null)
                        {
                            Log.Warning($"Bone: \"{name}\" not found");
                            continue;
                        }

                        if (config.UseSelection && !skeleton.GetIsBoneSelected(bone))
                        {
                            continue;
                        }

                        TransformPtrViewModel vm = bone.ViewModel;

                        if (PoseService.Instance.FreezePositions && savedBone.Position != null && config.LoadPositions)
                        {
                            vm.Position = (Vector)savedBone.Position;
                        }

                        if (PoseService.Instance.FreezeRotation && savedBone.Rotation != null && config.LoadRotations)
                        {
                            vm.Rotation = (Quaternion)savedBone.Rotation;
                        }

                        if (PoseService.Instance.FreezeScale && savedBone.Scale != null && config.LoadScales)
                        {
                            vm.Scale = (Vector)savedBone.Scale;
                        }

                        bone.ReadTransform();
                        bone.WriteTransform(skeleton, false);
                    }

                    await Task.Delay(1);
                }
            }

            await Task.Delay(100);

            skeletonMem.MemoryMode = MemoryModes.ReadWrite;

            await skeletonMem.ReadFromMemoryAsync();

            PoseService.Instance.CanEdit = true;
        }
示例#7
0
        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);
                }
            }
        }
示例#8
0
        public async Task Apply(ActorViewModel actor, SkeletonVisual3d skeleton, Configuration config, bool selectionOnly)
        {
            if (actor == null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (actor.ModelObject == null)
            {
                throw new Exception("Actor has no model");
            }

            if (actor.ModelObject.Skeleton == null)
            {
                throw new Exception("Actor model has no skeleton wrapper");
            }

            if (actor.ModelObject.Skeleton.Skeleton == null)
            {
                throw new Exception("Actor skeleton wrapper has no skeleton");
            }

            SkeletonViewModel skeletonMem = actor.ModelObject.Skeleton.Skeleton;

            skeletonMem.MemoryMode = MemoryModes.None;

            PoseService.Instance.SetEnabled(true);
            PoseService.Instance.CanEdit = false;
            await Task.Delay(100);

            // Facial expressions hack:
            // Since all facial bones are parented to the head, if we load the head rotation from
            // the pose that matches the expression, it wont break.
            // We then just set the head back to where it should be afterwards.
            BoneVisual3d?headBone = skeleton.GetIsHeadSelection() ? skeleton.GetBone("Head") : null;

            headBone?.ReadTransform(true);
            Quaternion?originalHeadRotation = headBone?.ViewModel.Rotation;

            if (this.Bones != null)
            {
                // Apply all transforms a few times to ensure parent-inherited values are caluclated correctly, and to ensure
                // we dont end up with some values read during a ffxiv frame update.
                for (int i = 0; i < 3; i++)
                {
                    foreach ((string name, Bone? savedBone) in this.Bones)
                    {
                        if (savedBone == null)
                        {
                            continue;
                        }

                        BoneVisual3d?bone = skeleton.GetBone(name);

                        if (bone == null)
                        {
                            Log.Warning($"Bone: \"{name}\" not found");
                            continue;
                        }

                        if (selectionOnly && !skeleton.GetIsBoneSelected(bone))
                        {
                            continue;
                        }

                        TransformPtrViewModel vm = bone.ViewModel;

                        if (PoseService.Instance.FreezePositions && savedBone.Position != null && config.LoadPositions)
                        {
                            vm.Position = (Vector)savedBone.Position;
                        }

                        if (PoseService.Instance.FreezeRotation && savedBone.Rotation != null && config.LoadRotations)
                        {
                            vm.Rotation = (Quaternion)savedBone.Rotation;
                        }

                        if (PoseService.Instance.FreezeScale && savedBone.Scale != null && config.LoadScales)
                        {
                            vm.Scale = (Vector)savedBone.Scale;
                        }

                        bone.ReadTransform();
                        bone.WriteTransform(skeleton, false);
                    }

                    await Task.Delay(1);
                }
            }

            // Restore the head bone rotation if we were only loading an expression
            if (headBone != null && originalHeadRotation != null)
            {
                headBone.ViewModel.Rotation = (Quaternion)originalHeadRotation;
                headBone.ReadTransform();
                headBone.WriteTransform(skeleton, true);
            }

            await Task.Delay(100);

            skeletonMem.MemoryMode = MemoryModes.ReadWrite;

            await skeletonMem.ReadFromMemoryAsync();

            PoseService.Instance.CanEdit = true;
        }