private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); var childrenIds = Children.Select(c => c.ID).ToArray(); if (childrenIds.Length == 0) { AnchorObjectSelector.Clear(); } else if (AnchorObjectSelector.Count != 1 || !AnchorObjectSelector.Where(i => childrenIds.Contains(i)).Any()) { AnchorObjectSelector.Clear(); AnchorObjectSelector.Add(childrenIds[0]); } // if the count of our children changed clear our cache of the bounds if (Children.Count != OriginalChildrenBounds.Count) { OriginalChildrenBounds.Clear(); } using (RebuildLock()) { var aabb = this.GetAxisAlignedBoundingBox(); // TODO: check if the has code for the children if (OriginalChildrenBounds.Count == 0) { this.Children.Modify(list => { foreach (var child in list) { OriginalChildrenBounds.Add(child.GetAxisAlignedBoundingBox()); } }); } this.Children.Modify(list => { if (list.Count == 0) { return; } int anchorIndex = AnchorObjectIndex; var anchorBounds = CurrentChildrenBounds[anchorIndex]; int i = 0; // first align the anchor object foreach (var child in list) { if (XAlign == Align.None || i == anchorIndex) { if (i < OriginalChildrenBounds.Count) { // make sure it is where it started AlignAxis(0, Align.Min, OriginalChildrenBounds[i].minXYZ.X, 0, child); } } if (YAlign == Align.None || i == anchorIndex) { if (i < OriginalChildrenBounds.Count) { AlignAxis(1, Align.Min, OriginalChildrenBounds[i].minXYZ.Y, 0, child); } } if (ZAlign == Align.None || i == anchorIndex) { if (i < OriginalChildrenBounds.Count) { AlignAxis(2, Align.Min, OriginalChildrenBounds[i].minXYZ.Z, 0, child); } } i++; } // the align all the objects to it i = 0; foreach (var child in list) { if (XAlign != Align.None && i != anchorIndex) { if (XAlign == Align.Origin) { // find the origin in world space of the child var firstOrigin = Vector3.Transform(Vector3.Zero, AnchorObject.WorldMatrix()); var childOrigin = Vector3.Transform(Vector3.Zero, child.WorldMatrix()); child.Translate(new Vector3(-(childOrigin - firstOrigin).X + (Advanced ? XOffset : 0), 0, 0)); } else { AlignAxis(0, XAlign, GetAlignToOffset(CurrentChildrenBounds, 0, (!Advanced || XAlignTo == Align.None) ? XAlign : XAlignTo), XOffset, child); } } if (YAlign != Align.None && i != anchorIndex) { if (YAlign == Align.Origin) { // find the origin in world space of the child var firstOrigin = Vector3.Transform(Vector3.Zero, AnchorObject.WorldMatrix()); var childOrigin = Vector3.Transform(Vector3.Zero, child.WorldMatrix()); child.Translate(new Vector3(0, -(childOrigin - firstOrigin).Y + (Advanced ? YOffset : 0), 0)); } else { AlignAxis(1, YAlign, GetAlignToOffset(CurrentChildrenBounds, 1, (!Advanced || YAlignTo == Align.None) ? YAlign : YAlignTo), YOffset, child); } } if (ZAlign != Align.None && i != anchorIndex) { if (ZAlign == Align.Origin) { // find the origin in world space of the child var firstOrigin = Vector3.Transform(Vector3.Zero, AnchorObject.WorldMatrix()); var childOrigin = Vector3.Transform(Vector3.Zero, child.WorldMatrix()); child.Translate(new Vector3(0, 0, -(childOrigin - firstOrigin).Z + (Advanced ? ZOffset : 0))); } else { AlignAxis(2, ZAlign, GetAlignToOffset(CurrentChildrenBounds, 2, (!Advanced || ZAlignTo == Align.None) ? ZAlign : ZAlignTo), ZOffset, child); } } i++; } }); } Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null)); }