protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { Brush clone = CreateBrush(oldContent); Size size = transitionElement.RenderSize; MeshGeometry3D leftDoor = CreateMesh(new Point3D(), new Vector3D(size.Width / 2, 0, 0), new Vector3D(0, size.Height, 0), 1, 1, new Rect(0, 0, 0.5, 1)); GeometryModel3D leftDoorGeometry = new GeometryModel3D(); leftDoorGeometry.Geometry = leftDoor; leftDoorGeometry.Material = new DiffuseMaterial(clone); AxisAngleRotation3D leftRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0); leftDoorGeometry.Transform = new RotateTransform3D(leftRotation); GeometryModel3D rightDoorGeometry = new GeometryModel3D(); MeshGeometry3D rightDoor = CreateMesh(new Point3D(size.Width / 2, 0, 0), new Vector3D(size.Width / 2, 0, 0), new Vector3D(0, size.Height, 0), 1, 1, new Rect(0.5, 0, 0.5, 1)); rightDoorGeometry.Geometry = rightDoor; rightDoorGeometry.Material = new DiffuseMaterial(clone); AxisAngleRotation3D rightRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0); rightDoorGeometry.Transform = new RotateTransform3D(rightRotation, size.Width, 0, 0); Model3DGroup doors = new Model3DGroup(); doors.Children.Add(leftDoorGeometry); doors.Children.Add(rightDoorGeometry); ModelVisual3D model = new ModelVisual3D(); model.Content = doors; // Replace old content in visual tree with new 3d model transitionElement.HideContent(oldContent); viewport.Children.Add(model); DoubleAnimation da = new DoubleAnimation(90 - 0.5 * FieldOfView, Duration); leftRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, da); da = new DoubleAnimation(-(90 - 0.5 * FieldOfView), Duration); rightRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, da); da = new DoubleAnimation(0, Duration); da.Completed += delegate { EndTransition(transitionElement, oldContent, newContent); }; clone.BeginAnimation(Brush.OpacityProperty, da); }
protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { Size size = transitionElement.RenderSize; // Create a rectangle MeshGeometry3D mesh = CreateMesh(new Point3D(), new Vector3D(size.Width, 0, 0), new Vector3D(0, size.Height, 0), 1, 1, new Rect(0, 0, 1, 1)); GeometryModel3D geometry = new GeometryModel3D(); geometry.Geometry = mesh; VisualBrush clone = new VisualBrush(oldContent); geometry.Material = new DiffuseMaterial(clone); ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; // Replace old content in visual tree with new 3d model transitionElement.HideContent(oldContent); viewport.Children.Add(model); Vector3D axis; Point3D center = new Point3D(); switch (Direction) { case RotateDirection.Left: axis = new Vector3D(0, 1, 0); break; case RotateDirection.Right: axis = new Vector3D(0, -1, 0); center = new Point3D(size.Width, 0, 0); break; case RotateDirection.Up: axis = new Vector3D(-1, 0, 0); break; default: axis = new Vector3D(1, 0, 0); center = new Point3D(0, size.Height, 0); break; } AxisAngleRotation3D rotation = new AxisAngleRotation3D(axis, 0); model.Transform = new RotateTransform3D(rotation, center); DoubleAnimation da = new DoubleAnimation(0, Duration); clone.BeginAnimation(Brush.OpacityProperty, da); da = new DoubleAnimation(90, Duration); da.Completed += delegate { EndTransition(transitionElement, oldContent, newContent); }; rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, da); }
protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { Size size = transitionElement.RenderSize; Point3D centerPoint; if (MouseAsCenter) { Point mouse2D = Mouse.GetPosition(transitionElement); centerPoint = new Point3D(mouse2D.X, mouse2D.Y, 0.5 * size.Width); } else { centerPoint = new Point3D(0.5 * size.Width, 0.5 * size.Height, 0.5 * size.Width); } int xparticles = 10, yparticles = 10; if (size.Width > size.Height) { yparticles = (int)(xparticles * size.Height / size.Width); } else { xparticles = (int)(yparticles * size.Width / size.Height); } double sx = 1.0 / xparticles, sy = 1.0 / yparticles; Vector3D u = new Vector3D(size.Width * sx, 0, 0); Vector3D v = new Vector3D(0, size.Height * sy, 0); Brush cloneBrush = CreateBrush(oldContent); Material clone = new DiffuseMaterial(cloneBrush); Vector3D[] velocities = new Vector3D[xparticles * yparticles]; Vector3D[] angularVelocities = new Vector3D[xparticles * yparticles]; Point3D[] centers = new Point3D[xparticles * yparticles]; Point3DCollection positions = new Point3DCollection(4 * xparticles * yparticles); PointCollection textures = new PointCollection(4 * xparticles * yparticles); Int32Collection triangles = new Int32Collection(6 * xparticles * yparticles); int n = 0; for (int i = 0; i < xparticles; i++) { for (int j = 0; j < yparticles; j++) { Point3D topleft = (Point3D)(i * u + j * v); positions.Add(topleft); positions.Add(topleft + u); positions.Add(topleft + u + v); positions.Add(topleft + v); textures.Add(new Point(i * sx, j * sy)); textures.Add(new Point((i + 1) * sx, j * sy)); textures.Add(new Point((i + 1) * sx, (j + 1) * sy)); textures.Add(new Point(i * sx, (j + 1) * sy)); triangles.Add(n); triangles.Add(n + 2); triangles.Add(n + 1); triangles.Add(n); triangles.Add(n + 3); triangles.Add(n + 2); Vector3D f0 = positions[n] - centerPoint; Vector3D f1 = positions[n + 1] - centerPoint; Vector3D f2 = positions[n + 2] - centerPoint; Vector3D f3 = positions[n + 3] - centerPoint; f0 = f0 / f0.LengthSquared; f1 = f1 / f1.LengthSquared; f2 = f2 / f2.LengthSquared; f3 = f3 / f3.LengthSquared; velocities[n / 4] = 2 * size.Width * (f0 + f1 + f2 + f3); Point3D center = centers[n / 4] = (Point3D)((i + 0.5) * u + (j + 0.5) * v); angularVelocities[n / 4] = 200 * (Vector3D.CrossProduct(f0, positions[n] - center) + Vector3D.CrossProduct(f1, positions[n + 1] - center) + Vector3D.CrossProduct(f2, positions[n + 2] - center) + Vector3D.CrossProduct(f3, positions[n + 3] - center)); n += 4; } } MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions = positions; mesh.TextureCoordinates = textures; mesh.TriangleIndices = triangles; GeometryModel3D geometryModel = new GeometryModel3D(mesh, clone); geometryModel.BackMaterial = clone; ModelVisual3D model = new ModelVisual3D(); model.Content = geometryModel; // Replace old content in visual tree with new 3d model transitionElement.HideContent(oldContent); viewport.Children.Add(model); DispatcherTimer timer = new DispatcherTimer(); int t = 0; double opacityDelta = 1.0 / (Duration.TimeSpan.Seconds * 60.0); timer.Interval = TimeSpan.FromSeconds(1.0 / 60.0); timer.Tick += delegate { t++; cloneBrush.Opacity = 1 - t * opacityDelta; if (cloneBrush.Opacity < opacityDelta) { timer.Stop(); EndTransition(transitionElement, oldContent, newContent); return; } mesh.Positions = null; AxisAngleRotation3D axisAngle = new AxisAngleRotation3D(); RotateTransform3D rotation = new RotateTransform3D(axisAngle, new Point3D()); for (int i = 0; i < positions.Count; i += 4) { Vector3D velocity = velocities[i / 4]; axisAngle.Axis = angularVelocities[i / 4]; axisAngle.Angle = angularVelocities[i / 4].Length; rotation.CenterX = centers[i / 4].X; rotation.CenterY = centers[i / 4].Y; rotation.CenterZ = centers[i / 4].Z; positions[i] = rotation.Transform(positions[i]) + velocity; positions[i + 1] = rotation.Transform(positions[i + 1]) + velocity; positions[i + 2] = rotation.Transform(positions[i + 2]) + velocity; positions[i + 3] = rotation.Transform(positions[i + 3]) + velocity; centers[i / 4] += velocity; } mesh.Positions = positions; }; timer.Start(); }
protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { Size size = transitionElement.RenderSize; Point3D origin = new Point3D(); // origin of 2nd face Vector3D u = new Vector3D(), v = new Vector3D(); // u & v vectors of 2nd face double angle = Angle; Point3D rotationCenter; Vector3D rotationAxis; RotateDirection direction = Direction; TranslateTransform3D translation = null; double angleRads = Angle * Math.PI / 180; if (direction == RotateDirection.Left || direction == RotateDirection.Right) { if (Contained) { rotationCenter = new Point3D(direction == RotateDirection.Left ? size.Width : 0, 0, 0); translation = new TranslateTransform3D(); DoubleAnimation x = new DoubleAnimation(direction == RotateDirection.Left ? -size.Width : size.Width, Duration); translation.BeginAnimation(TranslateTransform3D.OffsetXProperty, x); } else { rotationCenter = new Point3D(size.Width / 2, 0, size.Width / 2 * Math.Tan(angle / 2 * Math.PI / 180)); } rotationAxis = new Vector3D(0, 1, 0); if (direction == RotateDirection.Left) { u.X = -size.Width * Math.Cos(angleRads); u.Z = size.Width * Math.Sin(angleRads); origin.X = size.Width; } else { u.X = -size.Width * Math.Cos(angleRads); u.Z = -size.Width * Math.Sin(angleRads); origin.X = -u.X; origin.Z = -u.Z; } v.Y = size.Height; } else { if (Contained) { rotationCenter = new Point3D(0, direction == RotateDirection.Up ? size.Height : 0, 0); translation = new TranslateTransform3D(); DoubleAnimation y = new DoubleAnimation(direction == RotateDirection.Up ? -size.Height : size.Height, Duration); translation.BeginAnimation(TranslateTransform3D.OffsetYProperty, y); } else { rotationCenter = new Point3D(0, size.Height / 2, size.Height / 2 * Math.Tan(angle / 2 * Math.PI / 180)); } rotationAxis = new Vector3D(1, 0, 0); if (direction == RotateDirection.Up) { v.Y = -size.Height * Math.Cos(angleRads); v.Z = size.Height * Math.Sin(angleRads); origin.Y = size.Height; } else { v.Y = -size.Height * Math.Cos(angleRads); v.Z = -size.Height * Math.Sin(angleRads); origin.Y = -v.Y; origin.Z = -v.Z; } u.X = size.Width; } double endAngle = 180 - angle; if (direction == RotateDirection.Right || direction == RotateDirection.Up) endAngle = -endAngle; ModelVisual3D m1, m2; viewport.Children.Add(m1 = MakeSide(oldContent, new Point3D(), new Vector3D(size.Width,0,0), new Vector3D(0,size.Height,0), endAngle, rotationCenter, rotationAxis, null)); viewport.Children.Add(m2 = MakeSide(newContent, origin, u, v, endAngle, rotationCenter, rotationAxis, delegate { EndTransition(transitionElement, oldContent, newContent); })); m1.Transform = m2.Transform = translation; // Replace old and new content in visual tree with new 3d models transitionElement.HideContent(oldContent); transitionElement.HideContent(newContent); }
protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { int xparticles = 10, yparticles = 10; Size size = transitionElement.RenderSize; if (size.Width > size.Height) yparticles = (int)(xparticles * size.Height / size.Width); else xparticles = (int)(yparticles * size.Width / size.Height); MeshGeometry3D mesh = CreateMesh(new Point3D(), new Vector3D(size.Width, 0, 0), new Vector3D(0, size.Height, 0), xparticles - 1, yparticles - 1, new Rect(0, 0, 1, 1)); Brush cloneBrush = CreateBrush(oldContent); Material clone = new DiffuseMaterial(cloneBrush); double ustep = size.Width / (xparticles - 1), vstep = size.Height / (yparticles - 1); Point3DCollection points = mesh.Positions; Point3DCollection oldPoints = points.Clone(); double timeStep = 1.0 / 30.0; DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(timeStep); double time = 0; double duration = this.Duration.HasTimeSpan ? this.Duration.TimeSpan.TotalSeconds : 2; timer.Tick += delegate { time = time + timeStep; Point mousePos = Mouse.GetPosition(viewport); Point3D mousePos3D = new Point3D(mousePos.X, mousePos.Y, -10); // Cloth physics based on work of Thomas Jakobsen http://www.ioi.dk/~thomas for (int i = 0; i < oldPoints.Count; i++) { Point3D currentPoint = points[i]; Point3D newPoint = currentPoint + 0.9 * (currentPoint - oldPoints[i]); if (newPoint.Y > size.Height) newPoint.Y = size.Height; oldPoints[i] = newPoint; } //for (int j = 0; j < 5; j++) //for (int i = oldPoints.Count - 1; i > 0 ; i--) for (int a = yparticles - 1; a >= 0; a--) for (int b = xparticles - 1; b >= 0; b--) { int i = b * yparticles + a; // constrain with point to the left if (i > yparticles) Constrain(oldPoints, i, i - yparticles, ustep); // constrain with point to the top if (i % yparticles != 0) Constrain(oldPoints, i, i - 1, vstep); // constrain the sides if (a == 0) oldPoints[i] = new Point3D(oldPoints[i].X, 0, oldPoints[i].Z); if (a == yparticles - 1) oldPoints[i] = new Point3D(oldPoints[i].X, size.Height, oldPoints[i].Z); if (b == 0) oldPoints[i] = new Point3D(0, a * size.Height / (yparticles - 1), 0); if (b == xparticles - 1) { double angle = time / duration * Math.PI / (0.8 + 0.5 * (yparticles - (double)a) / yparticles); oldPoints[i] = new Point3D(size.Width * Math.Cos(angle), a * size.Height / (yparticles - 1), -size.Width * Math.Sin(angle)); } } if (time > (duration - 0)) { timer.Stop(); EndTransition(transitionElement, oldContent, newContent); } // Swap position arrays mesh.Positions = oldPoints; oldPoints = points; points = mesh.Positions; }; timer.Start(); GeometryModel3D geo = new GeometryModel3D(mesh, clone); geo.BackMaterial = clone; ModelVisual3D model = new ModelVisual3D(); model.Content = geo; // Replace old content in visual tree with new 3d model transitionElement.HideContent(oldContent); viewport.Children.Add(model); }