using System; using System.Collections.Generic; using System.Windows; using System.Windows.Media.Animation; using System.Windows.Media.Media3D; namespace HelixToolkit { /// /// The Expander3D translates all child Model3Ds relative to the ExpandOrigin. /// public class Expander3D : ModelVisual3D { public static readonly DependencyProperty ExpansionProperty = DependencyProperty.Register("Expansion", typeof (double), typeof (Expander3D), new UIPropertyMetadata(2.0, ExpansionChanged)); public static readonly DependencyProperty ExpandOriginProperty = DependencyProperty.Register("ExpandOrigin", typeof (Point3D?), typeof (Expander3D), new UIPropertyMetadata(null, ExpansionChanged)); private readonly Dictionary originalTransforms = new Dictionary(); private Point3D actualExpandOrigin; public double Expansion { get { return (double) GetValue(ExpansionProperty); } set { SetValue(ExpansionProperty, value); } } public Point3D? ExpandOrigin { get { return (Point3D?) GetValue(ExpandOriginProperty); } set { SetValue(ExpandOriginProperty, value); } } private static void ExpansionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((Expander3D) d).Expand(); } private void Expand() { if (!ExpandOrigin.HasValue) { if (Content != null) actualExpandOrigin = Content.Bounds.Location; } else { actualExpandOrigin = ExpandOrigin.Value; } Visual3DHelper.TraverseModel(Content, Expand); } private void Expand(GeometryModel3D model, Transform3D transformation) { Transform3D ot; if (originalTransforms.ContainsKey(model)) ot = originalTransforms[model]; else { ot = model.Transform; originalTransforms.Add(model, ot); } Transform3D totalTransform = Transform3DHelper.CombineTransform(transformation, ot); var mesh = model.Geometry as MeshGeometry3D; if (mesh == null) return; var bounds = new Rect3D(); foreach (int i in mesh.TriangleIndices) bounds.Union(totalTransform.Transform(mesh.Positions[i])); Point3D p = bounds.Location; Vector3D d = p - actualExpandOrigin; d *= Expansion; Point3D p2 = actualExpandOrigin + d; var t = new TranslateTransform3D(p2 - p); model.Transform = Transform3DHelper.CombineTransform(ot, t); } public void ExpandTo(double value, double animationTime) { var a = new DoubleAnimation(value, new Duration(TimeSpan.FromMilliseconds(animationTime))) {AccelerationRatio = 0.3, DecelerationRatio = 0.5}; BeginAnimation(ExpansionProperty, a); } } public class Exploder3D : ModelVisual3D { public static readonly DependencyProperty IsExplodingProperty = DependencyProperty.Register("IsExploding", typeof (bool), typeof (Exploder3D), new UIPropertyMetadata(false)); public bool IsExploding { get { return (bool) GetValue(IsExplodingProperty); } set { SetValue(IsExplodingProperty, value); } } } }