using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation;
using _3DTools;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace _3DView
{
/// <summary>
/// Rotation direction
/// </summary>
public enum RotateDirection : int
{
/// <summary>
/// None
/// </summary>
None = -1,
/// <summary>
/// Left direction
/// </summary>
Left = 0,
/// <summary>
/// Right direction
/// </summary>
Right = 1
}
/// <summary>
/// Interaction logic for _3DViewControl.xaml
/// </summary>
[CLSCompliant(false)]
public sealed partial class _3DViewControl : UserControl
{
/// <summary>
/// Default constructor
/// </summary>
public _3DViewControl()
{
InitializeComponent();
this.Children = new ObservableCollection<_3DViewElement>();
//Init();
}
/// <summary>
/// BackElement transf
/// </summary>
TransformGroup __BackElementRotation;
/// <summary>
/// Render transform for all content
/// </summary>
RotateTransform __ElementRotation;
#region Proprietes
/// <summary>
/// Gets or sets the current item
/// </summary>
public int CurrentItem
{ get; set; }
/// <summary>
/// Gets or sets the current item offset on Z axis
/// </summary>
public double CurrentItemOffset { get; set; }
/// <summary>
/// Gets or sets the miliseconds in the animation duration
/// </summary>
public int Duration { get; set; }
/// <summary>
/// Gets a collection of child _3DViewElement objects.
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ObservableCollection<_3DViewElement> Children { get; set; }
/// <summary>
/// Sets the Visibility of Flip button
/// </summary>
public bool ViewFlipButton
{
set
{
if (value == false)
this.FlipButton.Visibility = Visibility.Collapsed;
else
this.FlipButton.Visibility = Visibility.Visible;
}
get
{
return this.FlipButton.Visibility == Visibility.Visible;
}
}
/// <summary>
/// flip button content
/// </summary>
public string FlipButtonContent
{
set
{
if (value == null)
return;
this.FlipButton.Content = value;
}
}
/// <summary>
/// Gets or sets the Z coordonate of the camera position
/// </summary>
public double CameraZPosition
{
set
{
Point3D point = this.MyCamera.Position;
this.MyCamera.Position = new Point3D(point.X, point.Y, value);
}
get
{
return this.MyCamera.Position.Z;
}
}
#endregion
#region Methods
/// <summary>
/// Removes the element located at an index
/// </summary>
/// < </param>
public void RemoveAt(int index)
{
if (index < 0 || index >= this.MyInteractiveVisual3D.Children.Count)
return;
if (index > this.CurrentItem)
{
this.TranslateRightItems(RotateDirection.Left, index);
}
else
if (index < CurrentItem)
{
this.TranslateLeftItems(RotateDirection.Right, index + 1);
--this.CurrentItem;
}
else
{
InteractiveVisual3D currentChild = this.MyInteractiveVisual3D.Children[index] as InteractiveVisual3D;
if (currentChild == null) return;
Transform3DGroup currentTransf = currentChild.Transform as Transform3DGroup;
TranslateTransform3D currentTranslate = (currentTransf.Children[0] as TranslateTransform3D);
RotateTransform3D currentRotation = (currentTransf.Children[1] as RotateTransform3D);
DoubleAnimation myCurrentTranslateXDoubleAnimation = null,
myCurrentTranslateZDoubleAnimation = null,
myCurrentRotateDoubleAnimation = null;
//check for left child
if (index - 1 >= 0 && this.MyInteractiveVisual3D.Children[index - 1] != null)
{
currentChild = this.MyInteractiveVisual3D.Children[index - 1] as InteractiveVisual3D;
if (currentChild == null) return;
currentTransf = currentChild.Transform as Transform3DGroup;
currentTranslate = (currentTransf.Children[0] as TranslateTransform3D);
currentRotation = (currentTransf.Children[1] as RotateTransform3D);
// Animate the rotation's angle.
currentRotation.CenterX = -1; currentRotation.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = 45;
myCurrentRotateDoubleAnimation.To = 0;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 8));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = -1;
myCurrentTranslateXDoubleAnimation.To = 0;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
// Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = 0;
myCurrentTranslateZDoubleAnimation.To = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
//translate all left items
this.TranslateLeftItems(RotateDirection.Right, index);
this.CurrentItem = index - 1;
}
else
if (index + 1 < this.MyInteractiveVisual3D.Children.Count && this.MyInteractiveVisual3D.Children[index + 1] != null)
{
currentChild = this.MyInteractiveVisual3D.Children[index + 1] as InteractiveVisual3D;
if (currentChild == null) return;
Transform3DGroup currentTransf1 = currentChild.Transform as Transform3DGroup;
TranslateTransform3D currentTranslate1 = (currentTransf1.Children[0] as TranslateTransform3D);
RotateTransform3D currentRotation1 = (currentTransf1.Children[1] as RotateTransform3D);
// Animate the rotation's angle.
currentRotation1.CenterX = 1; currentRotation1.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = -45;
myCurrentRotateDoubleAnimation.To = 0;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation1.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
//currentTranslate = new TranslateTransform3D(-constVal, 0, this.CurrentItemOffset - constVal);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = 1;
myCurrentTranslateXDoubleAnimation.To = 0;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate1.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
//Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = 0;
myCurrentTranslateZDoubleAnimation.To = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
//Apply the animation to the Translate's OffsetX property.
currentTranslate1.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
this.TranslateRightItems(RotateDirection.Left, index + 1);
this.CurrentItem = index + 1;
}
}
this.MyInteractiveVisual3D.Children.RemoveAt(index);
this.Children.RemoveAt(index);
}
/// <summary>
/// Adds a new child
/// </summary>
/// <param name="child">Child to add</param>
public void AddNewChild(_3DView._3DViewElement child)
{
this.Children.Add(child);
//the content element
StackPanel panel = new StackPanel(); panel.RenderTransform = __ElementRotation;
if (child.FrontElement != null)
{
//reflection
Infragistics.ToyBox.Reflector r = new Infragistics.ToyBox.Reflector();
r.ReflectionTarget = child.FrontElement;
//add to content
panel.Children.Add(child.FrontElement);
panel.Children.Add(r);
}
if (child.BackElement != null)
{
//reflection
Infragistics.ToyBox.Reflector r1 = new Infragistics.ToyBox.Reflector();
r1.ReflectionTarget = child.BackElement;
//add to content
panel.Children.Add(child.BackElement); child.BackElement.Visibility = Visibility.Hidden;
panel.Children.Add(r1); r1.Visibility = Visibility.Hidden;
child.BackElement.RenderTransformOrigin = new Point(0.5, 0.5);
r1.RenderTransformOrigin = new Point(0.5, 0.5);
child.BackElement.RenderTransform = __BackElementRotation; r1.RenderTransform = __BackElementRotation;
}
//add 2D content
InteractiveVisual3D visualChild = new InteractiveVisual3D();
visualChild.IsBackVisible = true;
visualChild.Geometry = this.FindResource("ItemMesh") as MeshGeometry3D;
visualChild.Visual = panel;
Transform3DGroup transf = visualChild.Transform as Transform3DGroup;
if (transf == null) transf = CreateTransform();
RotateTransform3D rot = (transf.Children[1] as RotateTransform3D);
TranslateTransform3D translate = (transf.Children[0] as TranslateTransform3D);
transf.Children.Clear();
if (this.Children.Count > 1)
{
translate.OffsetX = this.Children.Count - this.CurrentItem - 1;
rot.CenterX = this.Children.Count - this.CurrentItem - 1;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)-45);
}
else
{
translate.OffsetZ = this.CurrentItemOffset;
rot.CenterX = 0;
rot.CenterZ = this.CurrentItemOffset;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, 0d);
}
transf.Children.Add(translate); transf.Children.Add(rot);
visualChild.Transform = transf;
this.MyInteractiveVisual3D.Children.Add(visualChild);
}
/// <summary>
/// Adds a new child
/// </summary>
/// <param name="child">Child to add</param>
void AddChild(_3DView._3DViewElement child)
{
//the content element
StackPanel panel = new StackPanel();
if (child.FrontElement != null)
{
//reflection
Infragistics.ToyBox.Reflector r = new Infragistics.ToyBox.Reflector();
r.ReflectionTarget = child.FrontElement;
//add to content
panel.Children.Add(child.FrontElement);
panel.Children.Add(r);
}
if (child.BackElement != null)
{
//reflection
Infragistics.ToyBox.Reflector r1 = new Infragistics.ToyBox.Reflector();
r1.ReflectionTarget = child.BackElement;
//add to content
panel.Children.Add(child.BackElement); child.BackElement.Visibility = Visibility.Collapsed;
panel.Children.Add(r1); r1.Visibility = Visibility.Collapsed;
child.BackElement.RenderTransformOrigin = new Point(0.5, 0.5);
r1.RenderTransformOrigin = new Point(0.5, 0.5);
child.BackElement.RenderTransform = __BackElementRotation; r1.RenderTransform = __BackElementRotation;
}
//add 2D content
InteractiveVisual3D visualChild = new InteractiveVisual3D();
visualChild.IsBackVisible = true;
visualChild.Geometry = this.FindResource("ItemMesh") as MeshGeometry3D;
visualChild.Visual = panel;
//add to list
this.MyInteractiveVisual3D.Children.Add(visualChild);
}
/// <summary>
/// Creates a new Transform3DGroup
/// </summary>
/// <returns></returns>
static Transform3DGroup CreateTransform()
{
Transform3DGroup transf = new Transform3DGroup();
transf.Children.Add(new TranslateTransform3D(0, 0, 0));
transf.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0)));
return transf;
}
/// <summary>
/// Makes 3D View initializations
/// </summary>
public void Init()
{
__ElementRotation = new RotateTransform(-90);
__BackElementRotation = new TransformGroup();
__BackElementRotation.Children.Add(new ScaleTransform(-1, 1));
if (this.CurrentItem == 0)
this.CurrentItem = 0;
if (this.CurrentItemOffset == 0)
this.CurrentItemOffset = 1;
if (this.Duration == 0)
this.Duration = 800;
this.SetChildTransform(RotateDirection.None);
}
/// <summary>
/// Translates all left items to a direction
/// </summary>
/// <param name="direction">Direction to translate</param>
/// <param name="toItem">From first item To item</param>
void TranslateLeftItems(RotateDirection direction, int toItem)
{
for (int i = 0; i < ((direction == RotateDirection.Right) ? toItem - 1 : toItem); ++i)
{
InteractiveVisual3D child = this.MyInteractiveVisual3D.Children[i] as InteractiveVisual3D;
if (child == null) return;
Transform3DGroup transf = child.Transform as Transform3DGroup;
TranslateTransform3D translate = (transf.Children[0] as TranslateTransform3D);
RotateTransform3D rot = (transf.Children[1] as RotateTransform3D);
DoubleAnimation myDoubleAnimation = null, myRotateDoubleAnimation = null;
switch (direction)
{
case RotateDirection.Right:
//Animate the translation's angle.
myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = translate.OffsetX;
myDoubleAnimation.To = translate.OffsetX + 1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
//Apply the animation to the translation's angle property.
translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myDoubleAnimation);
// Animate the rotation's center.
myRotateDoubleAnimation = new DoubleAnimation();
myRotateDoubleAnimation.From = rot.CenterX;
myRotateDoubleAnimation.To = rot.CenterX + 1;
myRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myRotateDoubleAnimation.AutoReverse = false;
myRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's centerx property.
rot.BeginAnimation(RotateTransform3D.CenterXProperty, myRotateDoubleAnimation);
break;
case RotateDirection.Left:
//Animate the translation's angle.
myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = translate.OffsetX;
myDoubleAnimation.To = translate.OffsetX - 1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the translation's angle property.
translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myDoubleAnimation);
// Animate the rotation's center.
myRotateDoubleAnimation = new DoubleAnimation();
myRotateDoubleAnimation.From = rot.CenterX;
myRotateDoubleAnimation.To = rot.CenterX - 1;
myRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myRotateDoubleAnimation.AutoReverse = false;
myRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's centerx property.
rot.BeginAnimation(RotateTransform3D.CenterXProperty, myRotateDoubleAnimation);
break;
default:
//do nothing
break;
}
}
}
/// <summary>
/// Translates all right items from an item to a direction
/// </summary>
/// <param name="direction">Direction to translate</param>
/// <param name="fromItem">From item to translate, to last item</param>
void TranslateRightItems(RotateDirection direction, int fromItem)
{
for (int i = ((direction == RotateDirection.Right) ? fromItem + 2 : fromItem + 1); i < this.MyInteractiveVisual3D.Children.Count; ++i)
{
InteractiveVisual3D child = this.MyInteractiveVisual3D.Children[i] as InteractiveVisual3D;
if (child == null) return;
Transform3DGroup transf = child.Transform as Transform3DGroup;
TranslateTransform3D translate = (transf.Children[0] as TranslateTransform3D);
RotateTransform3D rot = (transf.Children[1] as RotateTransform3D);
DoubleAnimation myDoubleAnimation = null, myRotateDoubleAnimation = null;
switch (direction)
{
case RotateDirection.Right:
// Animate the translation's offset.
myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = translate.OffsetX;
myDoubleAnimation.To = translate.OffsetX + 1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the translation's offsetx property.
translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myDoubleAnimation);
// Animate the rotation's center.
myRotateDoubleAnimation = new DoubleAnimation();
myRotateDoubleAnimation.From = rot.CenterX;
myRotateDoubleAnimation.To = rot.CenterX + 1;
myRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myRotateDoubleAnimation.AutoReverse = false;
myRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's centerx property.
rot.BeginAnimation(RotateTransform3D.CenterXProperty, myRotateDoubleAnimation);
break;
case RotateDirection.Left:
// Animate the translation's offset.
myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = translate.OffsetX;
myDoubleAnimation.To = translate.OffsetX - 1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the translation's angle property.
translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myDoubleAnimation);
// Animate the rotation's center.
myRotateDoubleAnimation = new DoubleAnimation();
myRotateDoubleAnimation.From = rot.CenterX;
myRotateDoubleAnimation.To = rot.CenterX - 1;
myRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
myRotateDoubleAnimation.AutoReverse = false;
myRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's centerx property.
rot.BeginAnimation(RotateTransform3D.CenterXProperty, myRotateDoubleAnimation);
break;
default:
//do nothing
break;
}
}
}
/// <summary>
/// Rotates the stack on a direction
/// </summary>
/// <param name="direction">Rotate direction</param>
void RotateStack(RotateDirection direction)
{
//reset the current item transformations
this.ResetCurrentItem(direction);
#region translate the left items with one unit
this.TranslateLeftItems(direction, this.CurrentItem);
#endregion
//bring to front next current item and put the last one in its place
int index = this.CurrentItem;
this.RotateItems(direction, ref index);
this.CurrentItem = index;
#region translate the right items with one unit
this.TranslateRightItems(direction, this.CurrentItem);
#endregion
}
/// <summary>
///
/// </summary>
/// <param name="direction"></param>
/// <param name="index"></param>
private void RotateItems(RotateDirection direction, ref int index)
{
InteractiveVisual3D currentChild = this.MyInteractiveVisual3D.Children[index] as InteractiveVisual3D;
if (currentChild == null) return;
Transform3DGroup currentTransf = currentChild.Transform as Transform3DGroup;
TranslateTransform3D currentTranslate = (currentTransf.Children[0] as TranslateTransform3D);
RotateTransform3D currentRotation = (currentTransf.Children[1] as RotateTransform3D);
DoubleAnimation myCurrentTranslateXDoubleAnimation = null,
myCurrentTranslateZDoubleAnimation = null,
myCurrentRotateDoubleAnimation = null;
switch (direction)
{
case RotateDirection.Right:
#region itemIndex
// Animate the rotation's angle.
currentRotation.CenterX = 1; currentRotation.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = 0;
myCurrentRotateDoubleAnimation.To = -45;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = 0;
myCurrentTranslateXDoubleAnimation.To = 1;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
// Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.To = 0;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
#endregion
--index;
#region itemIndex - 1
currentChild = this.MyInteractiveVisual3D.Children[index] as InteractiveVisual3D;
if (currentChild == null) return;
currentTransf = currentChild.Transform as Transform3DGroup;
currentTranslate = (currentTransf.Children[0] as TranslateTransform3D);
currentRotation = (currentTransf.Children[1] as RotateTransform3D);
// Animate the rotation's angle.
currentRotation.CenterX = -1; currentRotation.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = 45;
myCurrentRotateDoubleAnimation.To = 0;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = -1;
myCurrentTranslateXDoubleAnimation.To = 0;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
// Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = 0;
myCurrentTranslateZDoubleAnimation.To = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
#endregion
break;
case RotateDirection.Left:
#region itemIndex
// Animate the rotation's angle.
currentRotation.CenterX = -1; currentRotation.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = 0;
myCurrentRotateDoubleAnimation.To = 45;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
//currentTranslate = new TranslateTransform3D(-constVal, 0, this.CurrentItemOffset - constVal);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = 0;
myCurrentTranslateXDoubleAnimation.To = -1;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
//Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.To = 0;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
//Apply the animation to the Translate's OffsetX property.
currentTranslate.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
#endregion
++index;
#region itemIndex + 1
currentChild = this.MyInteractiveVisual3D.Children[index] as InteractiveVisual3D;
if (currentChild == null) return;
Transform3DGroup currentTransf1 = currentChild.Transform as Transform3DGroup;
TranslateTransform3D currentTranslate1 = (currentTransf1.Children[0] as TranslateTransform3D);
RotateTransform3D currentRotation1 = (currentTransf1.Children[1] as RotateTransform3D);
// Animate the rotation's angle.
currentRotation1.CenterX = 1; currentRotation1.CenterZ = 0;
myCurrentRotateDoubleAnimation = new DoubleAnimation();
myCurrentRotateDoubleAnimation.From = -45;
myCurrentRotateDoubleAnimation.To = 0;
myCurrentRotateDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentRotateDoubleAnimation.AutoReverse = false;
myCurrentRotateDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
currentRotation1.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myCurrentRotateDoubleAnimation);
//currentTranslate = new TranslateTransform3D(-constVal, 0, this.CurrentItemOffset - constVal);
// Animate the Translate's OffsetX.
myCurrentTranslateXDoubleAnimation = new DoubleAnimation();
myCurrentTranslateXDoubleAnimation.From = 1;
myCurrentTranslateXDoubleAnimation.To = 0;
myCurrentTranslateXDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateXDoubleAnimation.AutoReverse = false;
myCurrentTranslateXDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the Translate's OffsetX property.
currentTranslate1.BeginAnimation(TranslateTransform3D.OffsetXProperty, myCurrentTranslateXDoubleAnimation);
//Animate the Translate's OffsetZ.
myCurrentTranslateZDoubleAnimation = new DoubleAnimation();
myCurrentTranslateZDoubleAnimation.From = 0;
myCurrentTranslateZDoubleAnimation.To = this.CurrentItemOffset;
myCurrentTranslateZDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration / 2));
myCurrentTranslateZDoubleAnimation.AutoReverse = false;
myCurrentTranslateZDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
//Apply the animation to the Translate's OffsetX property.
currentTranslate1.BeginAnimation(TranslateTransform3D.OffsetZProperty, myCurrentTranslateZDoubleAnimation);
#endregion
break;
default:
//do nothing
break;
}
}
/// <summary>
/// Creates all children
/// </summary>
void CreateChildren()
{
for (int index = 0; index < this.Children.Count; ++index)
{
_3DViewElement child = this.Children[index];
this.AddChild(child);
}
}
/// <summary>
/// Transforms all children in a direction
/// </summary>
/// <param name="direction">Rotate direction</param>
void SetChildTransform(RotateDirection direction)
{
CreateChildren();
this.ResetCurrentItem(direction);
for (int i = 0; i < this.MyInteractiveVisual3D.Children.Count; ++i)
{
InteractiveVisual3D child = this.MyInteractiveVisual3D.Children[i] as InteractiveVisual3D;
if (child == null) return;
Transform3DGroup transf = child.Transform as Transform3DGroup;
if (transf == null) transf = CreateTransform();
FrameworkElement panel = child.Visual as FrameworkElement;
panel.RenderTransform = __ElementRotation;
int index = i;
RotateTransform3D rot = (transf.Children[1] as RotateTransform3D);
TranslateTransform3D translate = (transf.Children[0] as TranslateTransform3D);
transf.Children.Clear();
if (index == this.CurrentItem)
{
translate.OffsetX = 0;
translate.OffsetZ = this.CurrentItemOffset;
rot.CenterZ = this.CurrentItemOffset;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)0);
}
else
if (index < this.CurrentItem)
{
if (direction == RotateDirection.None)
{
translate.OffsetX = index - this.CurrentItem;
rot.CenterX = index - this.CurrentItem;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)45);
}
else if (direction == RotateDirection.Left)
{
//we want to see a left item
translate.OffsetX++;
translate.OffsetZ = 0;
rot.CenterX = translate.OffsetX;
rot.CenterZ = 0;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)45);
}
else
{
//we want to see a right item
translate.OffsetX--;
translate.OffsetZ = 0;
rot.CenterX = translate.OffsetX;
rot.CenterZ = 0;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)45);
}
}
else
{
if (direction == RotateDirection.None)
{
translate.OffsetX = index - this.CurrentItem;
rot.CenterX = index - this.CurrentItem;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)-45);
}
else if (direction == RotateDirection.Left)
{
//we want to see a left item
translate.OffsetX++;
translate.OffsetZ = 0;
rot.CenterX = translate.OffsetX;
rot.CenterZ = 0;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)-45);
}
else
{
//we want to see a right item
translate.OffsetX--;
translate.OffsetZ = 0;
rot.CenterX = translate.OffsetX;
rot.CenterZ = 0;
rot.Rotation.SetValue(AxisAngleRotation3D.AngleProperty, (double)-45);
}
}
transf.Children.Add(translate); transf.Children.Add(rot);
child.Transform = transf;
}
}
/// <summary>
/// Resets the current item transform
/// </summary>
/// <param name="direction"></param>
private void ResetCurrentItem(RotateDirection direction)
{
if (this.MyInteractiveVisual3D.Children.Count == 0) return;
switch (direction)
{
case RotateDirection.Left:
//reset current item
InteractiveVisual3D child1 = this.MyInteractiveVisual3D.Children[this.CurrentItem] as InteractiveVisual3D;
if (child1 == null) return;
Transform3DGroup transf1 = child1.Transform as Transform3DGroup;
transf1.Children[0] = new TranslateTransform3D(0, 0, this.CurrentItemOffset);
transf1.Children[1] = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0d));
child1.Transform = transf1;
break;
case RotateDirection.Right:
child1 = this.MyInteractiveVisual3D.Children[this.CurrentItem] as InteractiveVisual3D;
if (child1 == null) return;
transf1 = child1.Transform as Transform3DGroup;
transf1.Children[0] = new TranslateTransform3D(0, 0, this.CurrentItemOffset);
transf1.Children[1] = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0d));
child1.Transform = transf1;
break;
default:
break;
}
}
/// <summary>
/// Clears all children
/// </summary>
public void ClearChildren()
{
for (int i = this.Children.Count - 1; i >= 0; --i)
{
this.RemoveAt(i);
}
}
/// <summary>
/// Moves current item
/// </summary>
/// <param name="direction"></param>
public void MoveItem(RotateDirection direction)
{
switch (direction)
{
case RotateDirection.Left:
if (this.CurrentItem > 0)
this.RotateStack(RotateDirection.Right);
break;
case RotateDirection.Right:
if (this.CurrentItem < this.MyInteractiveVisual3D.Children.Count - 1)
this.RotateStack(RotateDirection.Left);
break;
default:
break;
}
}
#endregion
#region Event handlers
/// <summary>
/// Fires on Left rotation button click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LeftButton_Click(object sender, RoutedEventArgs e)
{
this.MoveItem(RotateDirection.Left);
}
/// <summary>
/// Fires on Right rotation button click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RightButton_Click(object sender, RoutedEventArgs e)
{
this.MoveItem(RotateDirection.Right);
}
/// <summary>
/// Flips current item
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FlipButton_Click(object sender, RoutedEventArgs e)
{
if (this.MyInteractiveVisual3D.Children.Count == 0) return;
Transform3DGroup transf = this.MyInteractiveVisual3D.Children[this.CurrentItem].Transform as Transform3DGroup;
RotateTransform3D rot = transf.Children[1] as RotateTransform3D;
double angle = (double)rot.Rotation.GetValue(AxisAngleRotation3D.AngleProperty);
rot = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), angle));
rot.CenterX = 0;
rot.CenterY = 0;
rot.CenterZ = this.CurrentItemOffset;
transf.Children[1] = rot;
// Animate the rotation's angle.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = angle;
myDoubleAnimation.To = 180 - Math.Abs(angle);
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
myDoubleAnimation.AutoReverse = false;
myDoubleAnimation.RepeatBehavior = new RepeatBehavior(1d);
// Apply the animation to the rotation's angle property.
rot.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, myDoubleAnimation);
InteractiveVisual3D currentChild = this.MyInteractiveVisual3D.Children[this.CurrentItem] as InteractiveVisual3D;
StackPanel content = currentChild.Visual as StackPanel;
if (angle == 0)
{
if (content.Children.Count > 0)
{
content.Children[0].Visibility = Visibility.Collapsed;
content.Children[1].Visibility = Visibility.Collapsed;
}
if (content.Children.Count > 2)
{
content.Children[2].Visibility = Visibility.Visible;
content.Children[3].Visibility = Visibility.Visible;
}
}
else
{
if (content.Children.Count > 2)
{
content.Children[2].Visibility = Visibility.Collapsed;
content.Children[3].Visibility = Visibility.Collapsed;
}
if (content.Children.Count > 0)
{
content.Children[0].Visibility = Visibility.Visible;
content.Children[1].Visibility = Visibility.Visible;
}
}
}
/// <summary>
/// Previous position point
/// </summary>
Point __PreviousPosition;
/// <summary>
/// Overrides the OnMouseMove
/// </summary>
/// <param name="e">EventArgs</param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
{
Point position = e.GetPosition(this);
if (position == __PreviousPosition) return;
if (position.Y < __PreviousPosition.Y - 50)
{
this.CameraZPosition -= 0.1d;
__PreviousPosition = position;
}
if (position.Y > __PreviousPosition.Y + 50)
{
this.CameraZPosition += 0.1d;
__PreviousPosition = position;
}
if (position.X > __PreviousPosition.X + 75)
{
this.MoveItem(RotateDirection.Left);
__PreviousPosition = position;
}
if (position.X < __PreviousPosition.X - 75)
{
this.MoveItem(RotateDirection.Right);
__PreviousPosition = position;
}
}
else
__PreviousPosition = e.GetPosition(this);
}
/// <summary>
/// Overrides the OnMouseDown
/// </summary>
/// <param name="e">EventArgs</param>
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
__PreviousPosition = e.GetPosition(this);
}
/// <summary>
/// Overrides the OnMouseUp
/// </summary>
/// <param name="e">EventArgs</param>
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
__PreviousPosition = e.GetPosition(this);
}
#endregion
}
/// <summary>
/// Class for an element : front and back
/// </summary>
[CLSCompliant(false)]
public sealed class _3DViewElement : FrameworkElement
{
/// <summary>
/// Gets the front element
/// </summary>
public FrameworkElement FrontElement { get; set; }
/// <summary>
/// Gets the back element
/// </summary>
public FrameworkElement BackElement { get; set; }
}
}