예제 #1
0
        private static Widget CreateMaterialEffectsPane(Model3DAttachment attachment)
        {
            var pane = new ThemedScrollView();

            pane.Content.Padding = new Thickness {
                Right = 10
            };
            var list = new Widget {
                Layout = new VBoxLayout(),
            };

            pane.Content.Layout = new VBoxLayout {
                Spacing = AttachmentMetrics.Spacing
            };
            pane.Content.AddNode(list);
            var widgetFactory = new AttachmentWidgetFactory <Model3DAttachment.MaterialEffect>(
                w => new MaterialEffectRow(w, attachment.MaterialEffects), attachment.MaterialEffects);

            widgetFactory.AddHeader(MaterialEffectRow.CreateHeader());
            widgetFactory.AddFooter(DeletableRow <Model3DAttachment.MaterialEffect> .CreateFooter(() => {
                history.DoTransaction(() => {
                    Core.Operations.InsertIntoList.Perform(
                        attachment.MaterialEffects,
                        attachment.MaterialEffects.Count,
                        new Model3DAttachment.MaterialEffect {
                        Name         = "MaterialEffect",
                        MaterialName = "MaterialName",
                        Path         = "MaterialPath",
                    }
                        );
                });
            }));
            list.Components.Add(widgetFactory);
            return(pane);
        }
예제 #2
0
        private static Widget CreateMeshOptionsPane(Model3DAttachment attachment)
        {
            var pane = new ThemedScrollView();

            pane.Content.Padding = new Thickness {
                Right = 10
            };
            var list = new Widget {
                Layout = new VBoxLayout(),
            };

            pane.Content.Layout = new VBoxLayout {
                Spacing = AttachmentMetrics.Spacing
            };
            pane.Content.AddNode(list);
            var widgetFactory = new AttachmentWidgetFactory <Model3DAttachment.MeshOption>(
                w => new MeshRow(w, attachment.MeshOptions), attachment.MeshOptions);

            widgetFactory.AddHeader(MeshRow.CreateHeader());
            widgetFactory.AddFooter(MeshRow.CreateFooter(() => {
                history.DoTransaction(() => Core.Operations.InsertIntoList.Perform(
                                          attachment.MeshOptions,
                                          attachment.MeshOptions.Count,
                                          new Model3DAttachment.MeshOption {
                    Id = "MeshOption"
                }
                                          ));
            }));
            list.Components.Add(widgetFactory);
            return(pane);
        }
예제 #3
0
        private static void CheckErrors(Model3DAttachment attachment, Model3D source)
        {
            if (new HashSet <string>(attachment.Animations.Select(a => a.Name)).Count != attachment.Animations.Count ||
                attachment.Animations.Any(a => a.Name == source.DefaultAnimation.Id)
                )
            {
                throw new Lime.Exception("Animations shouldn't have the same names");
            }

            if (new HashSet <string>(attachment.NodeComponents.Select(a => a.NodeId)).Count != attachment.NodeComponents.Count)
            {
                throw new Lime.Exception("Node components shouldn't have the same node ids");
            }
        }
예제 #4
0
        private static Widget CreateGeneralPane(Model3DAttachment attachment)
        {
            var pane = new ThemedScrollView();

            pane.Content.Padding = new Thickness(10, AttachmentMetrics.Spacing);
            pane.Content.Layout  = new VBoxLayout {
                Spacing = AttachmentMetrics.Spacing
            };
            new FloatPropertyEditor(Decorate(new PropertyEditorParams(
                                                 pane.Content,
                                                 attachment,
                                                 nameof(Model3DAttachment.ScaleFactor),
                                                 nameof(Model3DAttachment.ScaleFactor)), displayLabel: true));
            return(pane);
        }
예제 #5
0
        private static Widget CreateAnimationsPane(Model3DAttachment attachment)
        {
            var pane = new ThemedScrollView {
                Padding = new Thickness {
                    Right = 10
                },
            };
            var list = new Widget {
                Layout = new VBoxLayout(),
            };

            pane.Content.Layout = new VBoxLayout {
                Spacing = AttachmentMetrics.Spacing
            };
            pane.Content.AddNode(list);
            var widgetFactory = new AttachmentWidgetFactory <Model3DAttachment.Animation>(
                w => new AnimationRow(w, attachment.Animations), attachment.Animations);

            widgetFactory.AddHeader(AnimationRow.CreateHeader());
            widgetFactory.AddFooter(AnimationRow.CreateFooter(() => {
                history.DoTransaction(() => Core.Operations.InsertIntoList.Perform(
                                          attachment.Animations,
                                          attachment.Animations.Count,
                                          new Model3DAttachment.Animation {
                    Name = "Animation",
                }
                                          ));
            }));
            if (attachment.Animations.All(a => a.Name != Model3DAttachment.DefaultAnimationName))
            {
                attachment.Animations.Insert(0, new Model3DAttachment.Animation {
                    Name = Model3DAttachment.DefaultAnimationName,
                });
            }
            list.Components.Add(widgetFactory);
            return(pane);
        }
예제 #6
0
        private void CheckFbx(string path)
        {
            var target = Orange.The.UI.GetActiveTarget();

            using (var cacheBundle = OpenCacheBundle(AssetBundleFlags.Writable)) {
                Model3DAttachment attachment = null;
                Model3D           model      = null;
                var fbxPath     = Path.ChangeExtension(path, "fbx");
                var fbxExists   = base.FileExists(fbxPath);
                var fbxCached   = cacheBundle.FileExists(path);
                var fbxUpToDate = fbxCached == fbxExists &&
                                  (!fbxExists || cacheBundle.GetFileLastWriteTime(path) >= base.GetFileLastWriteTime(fbxPath));

                var attachmentPath     = Path.ChangeExtension(path, Model3DAttachment.FileExtension);
                var attachmentExists   = base.FileExists(attachmentPath);
                var attachmentCached   = cacheBundle.FileExists(attachmentPath);
                var attachmentUpToDate = attachmentCached == attachmentExists &&
                                         (!attachmentExists || cacheBundle.GetFileLastWriteTime(attachmentPath) >= base.GetFileLastWriteTime(attachmentPath));
                var fbxImportOptions = new FbxImportOptions {
                    Path            = fbxPath,
                    Target          = target,
                    ApplyAttachment = false
                };

                var attachmentMetaPath     = Path.ChangeExtension(path, Model3DAttachmentMeta.FileExtension);
                var attachmentMetaCached   = cacheBundle.FileExists(attachmentMetaPath);
                var attachmentMetaUpToDate = attachmentMetaCached &&
                                             cacheBundle.GetFileLastWriteTime(attachmentMetaPath) >= base.GetFileLastWriteTime(fbxPath);
                if (!attachmentMetaUpToDate && fbxExists)
                {
                    using (var fbxImporter = new FbxModelImporter(fbxImportOptions)) {
                        model = fbxImporter.LoadModel();
                        var meta = new Model3DAttachmentMeta();
                        foreach (var animation in model.Animations)
                        {
                            meta.SourceAnimationIds.Add(animation.Id);
                        }

                        foreach (var mesh in model.Descendants.OfType <Mesh3D>())
                        {
                            meta.MeshIds.Add(mesh.Id);
                            foreach (var submesh3D in mesh.Submeshes)
                            {
                                if (meta.SourceMaterials.All(m => m.Id != submesh3D.Material.Id))
                                {
                                    meta.SourceMaterials.Add(submesh3D.Material);
                                }
                            }
                        }
                        TangerinePersistence.Instance.WriteObjectToBundle(
                            cacheBundle,
                            attachmentMetaPath,
                            meta, Persistence.Format.Binary, Model3DAttachmentMeta.FileExtension,
                            base.GetFileLastWriteTime(fbxPath),
                            AssetAttributes.None, new byte[0]);
                    }
                }

                if (fbxUpToDate && attachmentUpToDate)
                {
                    return;
                }

                var animationPathPrefix = Orange.Toolbox.ToUnixSlashes(Path.GetDirectoryName(path) + "/" + Path.GetFileNameWithoutExtension(path) + "@");
                foreach (var assetPath in cacheBundle.EnumerateFiles().ToList())
                {
                    if (assetPath.EndsWith(".ant") && assetPath.StartsWith(animationPathPrefix))
                    {
                        cacheBundle.DeleteFile(assetPath);
                    }
                }

                if (fbxExists)
                {
                    if (model == null)
                    {
                        using (var fbxImporter = new FbxModelImporter(fbxImportOptions)) {
                            model = fbxImporter.LoadModel();
                        }
                    }
                    if (attachmentExists)
                    {
                        attachment = Model3DAttachmentParser.GetModel3DAttachment(fbxPath);
                        if (attachment.Animations != null)
                        {
                            foreach (var animation in attachment.Animations)
                            {
                                if (animation.SourceAnimationId == null)
                                {
                                    var ac = model.Components.Get <AnimationComponent>();
                                    animation.SourceAnimationId = ac != null && ac.Animations.Count > 0 ? ac.Animations[0].Id : null;
                                }
                            }
                        }
                        attachment.Apply(model);
                    }

                    foreach (var animation in model.Animations)
                    {
                        if (animation.IsLegacy)
                        {
                            continue;
                        }
                        var animationPathWithoutExt = animationPathPrefix + animation.Id;
                        animationPathWithoutExt = Animation.FixAntPath(animationPathWithoutExt);
                        var animationPath = animationPathWithoutExt + ".ant";
                        animation.ContentsPath = animationPathWithoutExt;
                        InternalPersistence.Instance.WriteObjectToBundle(cacheBundle, animationPath, animation.GetData(), Persistence.Format.Binary, ".ant",
                                                                         base.GetFileLastWriteTime(fbxPath), AssetAttributes.None, new byte[0]);
                        var animators = new List <IAnimator>();
                        animation.FindAnimators(animators);
                        foreach (var animator in animators)
                        {
                            animator.Owner.Animators.Remove(animator);
                        }
                    }
                    TangerinePersistence.Instance.WriteObjectToBundle(cacheBundle, path, model, Persistence.Format.Binary, ".t3d",
                                                                      base.GetFileLastWriteTime(fbxPath), AssetAttributes.None, new byte[0]);
                }
                else if (fbxCached)
                {
                    cacheBundle.DeleteFile(path);
                    cacheBundle.DeleteFile(attachmentMetaPath);
                }

                if (attachmentExists)
                {
                    TangerinePersistence.Instance.WriteObjectToBundle(
                        cacheBundle,
                        attachmentPath,
                        Model3DAttachmentParser.ConvertToModelAttachmentFormat(attachment), Persistence.Format.Binary, ".txt",
                        base.GetFileLastWriteTime(attachmentPath),
                        AssetAttributes.None, new byte[0]);
                }
                else if (attachmentCached)
                {
                    cacheBundle.DeleteFile(attachmentPath);
                }
            }
        }
예제 #7
0
        public AttachmentDialog(Model3D source)
        {
            Path        = source.ContentsPath;
            this.source = source;
            attachment  = new Model3DAttachmentParser().Parse(Path) ?? new Model3DAttachment {
                ScaleFactor = 1
            };
            window = new Window(new WindowOptions {
                ClientSize           = new Vector2(700, 400),
                FixedSize            = false,
                Title                = "Attachment3D",
                MinimumDecoratedSize = new Vector2(500, 300)
            });
            frame = new ThemedFrame {
                Padding    = new Thickness(8),
                LayoutCell = new LayoutCell {
                    StretchY = float.MaxValue
                },
                Layout = new StackLayout(),
            };
            content = new TabbedWidget();
            content.AddTab("General", CreateGeneralPane(), true);
            content.AddTab("Material Effects", CreateMaterialEffectsPane());
            content.AddTab("Mesh Options", CreateMeshOptionsPane());
            content.AddTab("Animations", CreateAnimationsPane());

            rootWidget = new ThemedInvalidableWindowWidget(window)
            {
                Padding = new Thickness(8),
                Layout  = new VBoxLayout(),
                Nodes   =
                {
                    content,
                    new Widget {
                        Layout = new HBoxLayout {
                            Spacing = 8
                        },
                        LayoutCell = new LayoutCell(Alignment.RightCenter),
                        Nodes      =
                        {
                            (okButton     = new ThemedButton {
                                Text      = "Ok"
                            }),
                            (cancelButton = new ThemedButton {
                                Text      = "Cancel"
                            }),
                        }
                    }
                }
            };
            cancelButton.Clicked += () => {
                window.Close();
                Core.UserPreferences.Instance.Load();
            };
            okButton.Clicked += () => {
                try {
                    CheckErrors();
                    window.Close();
                    Model3DAttachmentParser.Save(attachment, System.IO.Path.Combine(Project.Current.AssetsDirectory, Path));
                } catch (Lime.Exception e) {
                    new AlertDialog(e.Message).Show();
                }
            };
            rootWidget.FocusScope = new KeyboardFocusScope(rootWidget);
            rootWidget.LateTasks.AddLoop(() => {
                if (rootWidget.Input.ConsumeKeyPress(Key.Escape))
                {
                    window.Close();
                    Core.UserPreferences.Instance.Load();
                }
            });
        }