WPF Cover Flow Tutorial : Part 2

15 篇文章 0 订阅
Since Part 1, we now know how to display a cover in 3D.

In order to display a reflection mirror, we add another GeometryModel3D to our Model3DGroup. This new element will be based on these points :
  1. using Point2D = System.Windows.Point;  
  2. private Geometry3D TessellateMirror()  
  3. {  
  4.   var p0 = new Point3D(-1, -3, 0);  
  5.   var p1 = new Point3D(1, -3, 0);  
  6.   var p2 = new Point3D(1, -1, 0);  
  7.   var p3 = new Point3D(-1, -1, 0);  
  8.   var q0 = new Point2D(0, 1);  
  9.   var q1 = new Point2D(1, 1);  
  10.   var q2 = new Point2D(1, 0);  
  11.   var q3 = new Point2D(0, 0);  
  12.   return BuildMesh(p0, p1, p2, p3, q0, q1, q2, q3);  
  13. }  
We define the Point2D alias because of the conflict with System.Drawing.Point.

For the texture, we use a VisualBrush object and we apply a LinearGradientBrush to the image OpacityMask :
  1. using MediaColor = System.Windows.Media.Color;  
  2. private Material LoadImageMirror(ImageSource imSrc)  
  3. {  
  4.    var image = new System.Windows.Controls.Image();  
  5.    image.Source = imSrc;  
  6.    MediaColor startColor = MediaColor.FromArgb(127, 255, 255, 255);  
  7.    MediaColor endColor = MediaColor.FromArgb(127, 255, 255, 255);  
  8.    image.OpacityMask = new LinearGradientBrush(startColor, endColor, 90.0);  
  9.    var brush = new VisualBrush(image);  
  10.    return new DiffuseMaterial(brush);  
  11. }  

There are two possibilities to browse the covers :
  • Keep the camera at the very same place and translate/rotate all covers as we are browsing.
  • Transform only a few covers (e.g. the one currently selected) and move the camera.
The second solution will ensure better performance.The current cover will be put in front. The other covers will be rotated and placed on each side of the current cover. When the camera will move, the current cover will be moved back with the unselected ones, and the newly selected cover will be put in front.

There are two transformations : a rotation and a translation on X and Z axes. The rotation angle will be 90, 0 or -90 degrees. The Z translation will be 0 or 1 for the current cover. The X translation will be 0 for the current cover, or proportional to the distance from the origin. For each cover, we will save its position. We will compare the cover position with the current index to compute the transformation parameters. This gives us :
  1. private readonly int pos;  
  2. private double RotationAngle(int index)  
  3. {  
  4.     return Math.Sign(pos - index) * -90;  
  5. }  
  6. private double TranslationX(int index)  
  7. {  
  8.     return pos * .2 + Math.Sign(pos - index) * 1.6;  
  9. }  
  10. private double TranslationZ(int index)  
  11. {  
  12.     return pos == index ? 1 : 0;  
  13. }  
Applying the transformations to our Model3DGroup is easy. We create the transformation in the constructor with a default index of 0 :
  1. private readonly AxisAngleRotation3D rotation;  
  2. private readonly TranslateTransform3D translation;  
  3. public Cover(string imagePath, int pos)  
  4. {  
  5.     this.imagePath = imagePath;  
  6.     this.pos = pos;  
  7.   
  8.     ImageSource imSrc = LoadImageSource();  
  9.     modelGroup = new Model3DGroup();  
  10.     modelGroup.Children.Add(new GeometryModel3D(Tessellate(), LoadImage(imSrc)));  
  11.     modelGroup.Children.Add(new GeometryModel3D(TessellateMirror(), LoadImageMirror(imSrc)));  
  12.   
  13.     rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), RotationAngle(0));  
  14.     translation = new TranslateTransform3D(TranslationX(0), 0, TranslationZ(0));  
  15.     var transformGroup = new Transform3DGroup();  
  16.     transformGroup.Children.Add(new RotateTransform3D(rotation));  
  17.     transformGroup.Children.Add(translation);  
  18.     modelGroup.Transform = transformGroup;  
  19.     Content = modelGroup;  
  20. }  
Then, we will call the Animate method the transform the cover :
  1. public void Animate(int index)  
  2. {  
  3.     rotation.Angle = RotationAngle(index);  
  4.     translation.OffsetX = TranslationX(index);  
  5.     translation.OffsetZ = TranslationZ(index);  
  6. }  
If we create three covers, we realize that only one is visible :We need to replace our single light source with two different ones :
  1. <ModelVisual3D>  
  2.   <ModelVisual3D.Content>  
  3.     <DirectionalLight Color="White" Direction="1,0,-3" />  
  4.   </ModelVisual3D.Content>  
  5. </ModelVisual3D>  
  6. <ModelVisual3D>  
  7.   <ModelVisual3D.Content>  
  8.     <DirectionalLight Color="White" Direction="-1,0,-3" />  
  9.   </ModelVisual3D.Content>  
  10. </ModelVisual3D>  
Continue with Part 3. Download source.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值