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); }
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); }
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"); } }
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); }
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); }
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); } } }
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(); } }); }