实例介绍
【实例简介】
【实例截图】
【核心代码】
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Windows.Threading; using System.IO; using System.Security; namespace WPFDemo { public class FlipTile3D : WrapperElement<Viewport3D> { public FlipTile3D() : base(new Viewport3D()) { Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(setup3D)); m_listener.Rendering = tick; this.Unloaded = delegate(object sender, RoutedEventArgs e) { m_listener.StopListening(); }; } #region render/layout overrides protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { base.OnRender(drawingContext); drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(this.RenderSize)); } #endregion #region mouse overrides protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) { _lastMouse = e.GetPosition(this); } protected override void OnMouseLeave(MouseEventArgs e) { _lastMouse = new Point(double.NaN, double.NaN); } protected override void OnMouseDown(MouseButtonEventArgs e) { _isFlipped = !_isFlipped; if (_isFlipped) { setClickedItem(e.GetPosition(this)); } } #endregion #region private methods private void setClickedItem(Point point) { //move point to center point -= (new Vector(this.ActualWidth / 2, this.ActualHeight / 2)); //flip it point.Y *= -1; //scale it to 1x1 dimentions double scale = Math.Min(this.ActualHeight, this.ActualWidth) / 2; point = (Point)(((Vector)point) / scale); //set it up so that bottomLeft = 0,0 & topRight = 1,1 (positive Y is up) point = (Point)(((Vector)point new Vector(1, 1)) * .5); //scale up so that the point coordinates align w/ the x/y scale point.Y *= c_yCount; point.X *= c_xCount; //now we have the indicies of the x & y of the tile clicked int yIndex = (int)Math.Floor(point.Y); int xIndex = (int)Math.Floor(point.X); int tileIndex = yIndex * c_xCount xIndex; _backMaterial.Brush = _tiles[tileIndex].DiffuseMaterial.Brush; } private void setup3D() { //perf improvement. Clipping in 3D is expensive. Avoid if you can! WrappedElement.ClipToBounds = false; PerspectiveCamera camera = new PerspectiveCamera( new Point3D(0, 0, 3.73), //position new Vector3D(0, 0, -1), //lookDirection new Vector3D(0, 1, 0), //upDirection 30 //FOV ); WrappedElement.Camera = camera; Model3DGroup everything = new Model3DGroup(); Model3DGroup lights = new Model3DGroup(); DirectionalLight whiteLight = new DirectionalLight(Colors.White, new Vector3D(0, 0, -1)); lights.Children.Add(whiteLight); everything.Children.Add(lights); ModelVisual3D model = new ModelVisual3D(); double tileSizeX = 2.0 / c_xCount; double startX = -((double)c_xCount) / 2 * tileSizeX tileSizeX / 2; double startY = -((double)c_yCount) / 2 * tileSizeX tileSizeX / 2; int index; Size tileTextureSize = new Size(1.0 / c_xCount, 1.0 / c_yCount); //so, tiles are numbers, left-to-right (ascending x), bottom-to-top (ascending y) for (int y = 0; y < c_yCount; y ) { for (int x = 0; x < c_xCount; x ) { index = y * c_xCount x; Rect backTextureCoordinates = new Rect( x * tileTextureSize.Width, // this will give you a headache. Exists since we are going // from bottom bottomLeft of 3D space (negative Y is down), // but texture coor are negative Y is up 1 - y * tileTextureSize.Height - tileTextureSize.Height, tileTextureSize.Width, tileTextureSize.Height); _tiles[index] = new TileData(); _tiles[index].Setup3DItem( everything, getMaterial(index), new Size(tileSizeX, tileSizeX), new Point(startX x * tileSizeX, startY y * tileSizeX), _backMaterial, backTextureCoordinates); } } model.Content = everything; WrappedElement.Children.Add(model); //start the per-frame tick for the physics m_listener.StartListening(); } private void tick(object sender, EventArgs e) { Vector mouseFixed = fixMouse(_lastMouse, this.RenderSize); for (int i = 0; i < _tiles.Length; i ) { //TODO: unwire Render event if nothing happens _tiles[i].TickData(mouseFixed, _isFlipped); } } private static Vector fixMouse(Point mouse, Size size) { Debug.Assert(size.Width >= 0 && size.Height >= 0); double scale = Math.Max(size.Width, size.Height) / 2; // Translate y going down to y going up mouse.Y = -mouse.Y size.Height; mouse.Y -= size.Height / 2; mouse.X -= size.Width / 2; Vector v = new Vector(mouse.X, mouse.Y); v /= scale; return v; } #endregion #region Implementation private DiffuseMaterial getMaterial(int index) { return _materials[index % _materials.Count]; } private readonly IList<DiffuseMaterial> _materials = GetSamplePictures("Picture"); private static IList<DiffuseMaterial> GetSamplePictures(string Path) { IList<DiffuseMaterial> materials; IList<string> files = null; if (!string.IsNullOrEmpty(Path)) { files = new List<string>(); try { DirectoryInfo di = new DirectoryInfo(Path); if (di.Exists) { foreach (FileInfo fileInfo in di.GetFiles("*.jpg")) { files.Add(fileInfo.FullName); if (files.Count > 50) break; } } } catch (IOException) { } catch (ArgumentException) { } catch (SecurityException) { } } if (files.Count > 0) { materials = new List<DiffuseMaterial>(); foreach (string file in files) { Uri uri = new Uri(file); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.UriSource = uri; bitmapImage.DecodePixelWidth = 320; bitmapImage.DecodePixelHeight = 240; bitmapImage.EndInit(); bitmapImage.Freeze(); ImageBrush imageBrush = new ImageBrush(bitmapImage); imageBrush.Stretch = Stretch.UniformToFill; imageBrush.ViewportUnits = BrushMappingMode.Absolute; imageBrush.Freeze(); DiffuseMaterial diffuseMaterial = new DiffuseMaterial(imageBrush); materials.Add(diffuseMaterial); } } else { Brush[] brushes = new Brush[] { Brushes.LightBlue, Brushes.Pink, Brushes.LightGray, Brushes.Yellow, Brushes.Orange, Brushes.LightGreen }; DiffuseMaterial[] materialsArray = brushes.Select(brush => new DiffuseMaterial(brush)).ToArray(); materials = materialsArray; } return materials; } private Point _lastMouse = new Point(double.NaN, double.NaN); private bool _isFlipped; private readonly TileData[] _tiles = new TileData[c_xCount * c_yCount]; private readonly DiffuseMaterial _backMaterial = new DiffuseMaterial(); private readonly CompositionTargetRenderingListener m_listener = new CompositionTargetRenderingListener(); private const int c_xCount = 7, c_yCount = 7; #endregion } }
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论