예제 #1
0
        public BoneVisual3d(TransformPtrViewModel transform, SkeletonVisual3d skeleton, string name)
        {
            this.ViewModel = transform;
            this.Skeleton  = skeleton;

            this.rotation = new RotateTransform3D();
            this.position = new TranslateTransform3D();

            Transform3DGroup transformGroup = new Transform3DGroup();

            transformGroup.Children.Add(this.rotation);
            transformGroup.Children.Add(this.position);

            this.Transform = transformGroup;

            PaletteHelper ph = new PaletteHelper();
            ITheme        t  = ph.GetTheme();

            this.defaultMaterial  = new DiffuseMaterial(new SolidColorBrush(WinColor.FromArgb(64, 0, 0, 0)));
            this.hoverMaterial    = new EmissiveMaterial(new SolidColorBrush(t.PrimaryDark.Color));
            this.selectedMaterial = new EmissiveMaterial(new SolidColorBrush(t.PrimaryMid.Color));

            System.Windows.Media.Color c1 = System.Windows.Media.Color.FromArgb(200, 255, 255, 255);
            this.sphere          = new Sphere();
            this.sphere.Radius   = 0.02;
            this.sphere.Material = this.defaultMaterial;
            this.Children.Add(this.sphere);

            this.OriginalBoneName = name;
            this.BoneName         = name;

            this.Skeleton.PropertyChanged += this.OnSkeletonPropertyChanged;
        }
예제 #2
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;
        }
예제 #3
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;
        }