// TODO: Figure out how best to collapse the InsertionGroup after the load task completes public InsertionGroupObject3D(IEnumerable <ILibraryItem> items, View3DWidget view3DWidget, InteractiveScene scene, Vector2 newItemOffset, Action <IObject3D, IEnumerable <IObject3D> > layoutParts, bool trackSourceFiles = false) { if (items == null) { return; } this.layoutParts = layoutParts; // Add a temporary placeholder to give us some bounds this.scene = scene; this.view3DWidget = view3DWidget; this.LoadingItemsTask = Task.Run(async() => { var offset = Matrix4X4.Identity; // Add the placeholder 'Loading...' object var placeholderItem = new Object3D() { Mesh = placeHolderMesh, Matrix = Matrix4X4.Identity, Parent = this }; this.Children.Add(placeholderItem); var itemsToLoad = items.Where(item => item.IsContentFileType()).ToList(); // Filter to content file types only foreach (var item in itemsToLoad) { // Acquire var progressControl = new DragDropLoadProgress(view3DWidget, null, ApplicationController.Instance.Theme); // Position at accumulating offset placeholderItem.Matrix *= Matrix4X4.CreateTranslation(newItemOffset.X, (double)newItemOffset.Y, 0); placeholderItem.Visible = true; progressControl.TrackingObject = placeholderItem; var loadedItem = await item.CreateContent(progressControl.ProgressReporter); if (loadedItem != null) { var aabb = loadedItem.GetAxisAlignedBoundingBox(); // lets move the cube to the center of the loaded thing placeholderItem.Matrix *= Matrix4X4.CreateTranslation(-10 + aabb.XSize / 2, 0, 0); placeholderItem.Visible = false; // Copy scale/rotation/translation from the source and Center loadedItem.Matrix = loadedItem.Matrix * Matrix4X4.CreateTranslation((double)-aabb.Center.X, (double)-aabb.Center.Y, (double)-aabb.MinXYZ.Z) * placeholderItem.Matrix; // check if the item has 0 height (it is probably an image) if (loadedItem.ZSize() == 0) { // raise it up a bit so it is not z fighting with the bed loadedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, .1); } loadedItem.Color = loadedItem.Color; // Set mesh path if tracking requested if (trackSourceFiles && item is FileSystemFileItem fileItem && item.IsMeshFileType()) { loadedItem.MeshPath = fileItem.Path; } this.Children.Add(loadedItem); loadedItem.MakeNameNonColliding(); // Adjust next item position newItemOffset.X = loadedItem.GetAxisAlignedBoundingBox().XSize / 2 + 10; } // the 1.3 is so the progress bar will collapse after going past 1 progressControl.ProgressReporter(1.3, ""); } this.Children.Remove(placeholderItem); this.Collapse(); this.Invalidate(InvalidateType.Children); }); }
// TODO: Figure out how best to collapse the InsertionGroup after the load task completes public InsertionGroupObject3D(IEnumerable <ILibraryItem> items, View3DWidget view3DWidget, InteractiveScene scene, Vector2 bedCenter, Func <bool> dragOperationActive, bool trackSourceFiles = false) { if (items == null) { return; } // Add a temporary placeholder to give us some bounds this.scene = scene; this.view3DWidget = view3DWidget; this.LoadingItemsTask = Task.Run((Func <Task>)(async() => { var newItemOffset = Vector2.Zero; if (dragOperationActive != null && !dragOperationActive()) { newItemOffset = bedCenter; } var offset = Matrix4X4.Identity; // Add the placeholder 'Loading...' object var placeholderItem = new Object3D() { Mesh = placeHolderMesh, Matrix = Matrix4X4.Identity, Parent = this }; this.Children.Add(placeholderItem); // Filter to content file types only foreach (var item in items.Where(item => item.IsContentFileType()).ToList()) { // Acquire var progressControl = new DragDropLoadProgress(view3DWidget, null); // Position at accumulating offset placeholderItem.Matrix *= Matrix4X4.CreateTranslation(newItemOffset.X, (double)newItemOffset.Y, 0); placeholderItem.Visible = true; progressControl.TrackingObject = placeholderItem; var loadedItem = await item.CreateContent(progressControl.ProgressReporter); if (loadedItem != null) { var aabb = loadedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity); // lets move the cube to the center of the loaded thing placeholderItem.Matrix *= Matrix4X4.CreateTranslation(-10 + aabb.XSize / 2, 0, 0); placeholderItem.Visible = false; // Copy scale/rotation/translation from the source and Center loadedItem.Matrix = loadedItem.Matrix * Matrix4X4.CreateTranslation((double)-aabb.Center.X, (double)-aabb.Center.Y, (double)-aabb.minXYZ.Z) * placeholderItem.Matrix; // check if the item has 0 height (it is probably an image) if (loadedItem.ZSize() == 0) { // raise it up a bit so it is not z fighting with the bed loadedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, .1); } loadedItem.Color = loadedItem.Color; // Set mesh path if tracking requested if (trackSourceFiles && item is FileSystemFileItem fileItem && item.IsMeshFileType()) { loadedItem.MeshPath = fileItem.Path; } // Notification should force invalidate and redraw //progressReporter?.Invoke(1, ""); this.Children.Add(loadedItem); loadedItem.MakeNameNonColliding(); // Wait for content to load // Adjust next item position // TODO: do something more interesting than increment in x newItemOffset.X = loadedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity).XSize / 2 + 10; } progressControl.ProgressReporter(1.3, ""); } this.Children.Remove(placeholderItem); this.ContentAcquired = true; ContentLoaded?.Invoke(this, null); if (dragOperationActive != null && !dragOperationActive()) { this.Collapse(); } this.Invalidate(new InvalidateArgs(this, InvalidateType.Content)); })); }