Esempio n. 1
0
        private async Task GenerateBones()
        {
            this.Generating = true;

            await Dispatch.MainThread();

            this.Bones.Clear();

            if (this.Actor?.ModelObject?.Skeleton?.Skeleton == null)
            {
                return;
            }

            SkeletonViewModel skeletonVm = this.Actor.ModelObject.Skeleton.Skeleton;

            ////TemplateSkeleton template = skeletonVm.GetTemplate(this.Actor);
            await this.Generate(skeletonVm);

            // Map eyes together if they exist
            BoneVisual3d?lEye = this.GetBone("EyeLeft");
            BoneVisual3d?rEye = this.GetBone("EyeRight");

            if (lEye != null && rEye != null)
            {
                lEye.LinkedEye = rEye;
                rEye.LinkedEye = lEye;
            }

            foreach (BoneVisual3d bone in this.Bones)
            {
                bone.ReadTransform();
            }

            foreach (BoneVisual3d bone in this.Bones)
            {
                bone.ReadTransform();
            }

            this.Generating = false;
        }
        public static SkeletonFile?GetSkeletonFile(this SkeletonViewModel self, ActorViewModel actor)
        {
            int          maxDepth = int.MinValue;
            SkeletonFile?maxSkel  = null;

            foreach (SkeletonFile template in PoseService.BoneNameFiles)
            {
                if (template.IsValid(self, actor))
                {
                    if (template.Depth > maxDepth)
                    {
                        maxDepth = template.Depth;
                        maxSkel  = template;
                    }
                }
            }

            if (maxSkel != null)
            {
                return(maxSkel);
            }

            return(null);
        }
Esempio n. 3
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;
        }
Esempio n. 4
0
        private async Task Generate(SkeletonViewModel memory)
        {
            SkeletonFile?skeletonFile = memory.GetSkeletonFile(this.Actor);

            bool autoSkeleton = false;

            if ((skeletonFile == null || skeletonFile.Parenting == null) && GposeService.Instance.IsGpose)
            {
                string message = LocalizationService.GetStringFormatted("Pose_GenerateSkeleton", this.Actor.DisplayName);
                bool?  result  = await GenericDialog.Show(message, LocalizationService.GetString("Pose_GenerateSkeletonTitle"), MessageBoxButton.YesNo);

                autoSkeleton = result == true;
            }

            // Get all bones
            this.Bones.Clear();
            this.GetBones(memory.Body, "Body");
            this.GetBones(memory.Head, "Head");
            this.GetBones(memory.Hair, "Hair");
            this.GetBones(memory.Met, "Met");
            this.GetBones(memory.Top, "Top");

            if (skeletonFile != null && skeletonFile.BoneNames != null)
            {
                foreach (BoneVisual3d bone in this.Bones)
                {
                    string?newName;
                    if (skeletonFile.BoneNames.TryGetValue(bone.BoneName, out newName))
                    {
                        bone.BoneName = newName;
                    }
                }
            }

            if (autoSkeleton)
            {
                try
                {
                    // gnerate parenting
                    await ParentingUtility.ParentBones(this, this.Bones);
                }
                catch (Exception ex)
                {
                    Log.Write(Severity.Error, new Exception("Failed to generate skeleton file.", ex));
                    return;
                }

                if (skeletonFile == null)
                {
                    skeletonFile           = new SkeletonFile();
                    skeletonFile.ModelType = this.Actor.ModelType;
                    skeletonFile.Race      = this.Actor.Customize?.Race;
                }

                skeletonFile.Parenting = new Dictionary <string, string>();
                foreach (BoneVisual3d bone in this.Bones)
                {
                    if (bone.Parent == null)
                    {
                        continue;
                    }

                    skeletonFile.Parenting.Add(bone.BoneName, bone.Parent.BoneName);
                }

                PoseService.SaveTemplate(skeletonFile);
            }
            else if (skeletonFile != null && skeletonFile.Parenting != null)
            {
                // parenting from file
                foreach (BoneVisual3d bone in this.Bones)
                {
                    string?parentBoneName;
                    if (skeletonFile.Parenting.TryGetValue(bone.BoneName, out parentBoneName))
                    {
                        bone.Parent = this.GetBone(parentBoneName);

                        if (bone.Parent == null)
                        {
                            throw new Exception($"Failed to find target parent bone: {parentBoneName}");
                        }
                    }
                    else
                    {
                        this.Children.Add(bone);
                    }
                }
            }
            else
            {
                // no parenting...
                PoseService.Instance.EnableParenting = false;

                foreach (BoneVisual3d bone in this.Bones)
                {
                    this.Children.Add(bone);
                }
            }
        }
Esempio n. 5
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;
        }
Esempio n. 6
0
        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
            SkeletonViewModel vm = this.DataContext as SkeletonViewModel;

            this.Viewport.Children.Remove(vm.Root);
        }
Esempio n. 7
0
        private void GenerateBones()
        {
            this.Bones = new List <BoneVisual3d>();

            // only show actors that have a body
            if (this.Actor?.ModelObject?.Skeleton?.Skeleton == null)
            {
                return;
            }

            SkeletonViewModel skeletonVm = this.Actor.ModelObject.Skeleton.Skeleton;

            if (skeletonVm.Body == null)
            {
                return;
            }

            // Body bones
            List <BoneVisual3d> bodyBones = new List <BoneVisual3d>();

            for (int i = 0; i < skeletonVm.Body.Count; i++)
            {
                BoneVisual3d bone = new BoneVisual3d(skeletonVm.Body.Transforms[i], this);
                bodyBones.Add(bone);
                this.Bones.Add(bone);
                ////this.RootBones.Add(bone);
            }

            for (int i = 0; i < skeletonVm.Body.Count; i++)
            {
                int parent = SkeletonUtility.PlayerBodyParents[i];
                if (parent == -1 || parent > bodyBones.Count)
                {
                    this.Children.Add(bodyBones[i]);
                }
                else
                {
                    bodyBones[i].Parent = bodyBones[parent];
                }
            }

            int headBoneIndex = SkeletonUtility.BodyBoneIndexLookup["Head"];

            BoneVisual3d?headRoot = null;

            if (headBoneIndex < bodyBones.Count)
            {
                headRoot = bodyBones[headBoneIndex];
            }

            if (skeletonVm.Head != null)
            {
                foreach (TransformViewModel boneTrans in skeletonVm.Head.Transforms)
                {
                    BoneVisual3d bone = new BoneVisual3d(boneTrans, this);
                    this.Bones.Add(bone);
                    bone.Parent = headRoot;

                    if (headRoot == null)
                    {
                        this.Children.Add(bone);
                    }
                }
            }

            if (skeletonVm.Hair != null)
            {
                foreach (TransformViewModel boneTrans in skeletonVm.Hair.Transforms)
                {
                    BoneVisual3d bone = new BoneVisual3d(boneTrans, this);
                    this.Bones.Add(bone);
                    bone.Parent = headRoot;

                    if (headRoot == null)
                    {
                        this.Children.Add(bone);
                    }
                }
            }

            if (skeletonVm.Met != null)
            {
                foreach (TransformViewModel boneTrans in skeletonVm.Met.Transforms)
                {
                    BoneVisual3d bone = new BoneVisual3d(boneTrans, this);
                    this.Bones.Add(bone);
                    this.Children.Add(bone);
                }
            }

            if (skeletonVm.Top != null)
            {
                foreach (TransformViewModel boneTrans in skeletonVm.Top.Transforms)
                {
                    BoneVisual3d bone = new BoneVisual3d(boneTrans, this);
                    this.Bones.Add(bone);
                    this.Children.Add(bone);
                }
            }

            foreach (BoneVisual3d bone in this.Bones)
            {
                bone.ReadTransform();
            }

            foreach (BoneVisual3d bone in this.Bones)
            {
                bone.ReadTransform();
            }
        }
 public SkeletonView()
 {
     InitializeComponent();
     DataContext = SkeletonViewModel;
     SkeletonViewModel.Initialize(frame, NavView, KeyboardAccelerators);
 }