static InteractiveVisual3D() { _defaultMaterialPropertyValue = new DiffuseMaterial(); _defaultMaterialPropertyValue.SetValue(InteractiveVisual3D.IsInteractiveMaterialProperty, true); _defaultMaterialPropertyValue.Freeze(); MaterialProperty = DependencyProperty.Register("Material", typeof(Material), typeof(InteractiveVisual3D), new PropertyMetadata(_defaultMaterialPropertyValue, new PropertyChangedCallback(OnMaterialPropertyChanged))); }
private FrameworkElement CreateVisualChild() { MeshGeometry3D simpleQuad = new MeshGeometry3D() { Positions = new Point3DCollection(_mesh), TextureCoordinates = new PointCollection(_texCoords), TriangleIndices = new Int32Collection(_indices) }; // Front material is interactive, back material is not. Material frontMaterial = new DiffuseMaterial(Brushes.White); frontMaterial.SetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty, true); VisualBrush vb = new VisualBrush(_logicalChild); SetCachingForObject(vb); // big perf wins by caching!! Material backMaterial = new DiffuseMaterial(vb); _rotationTransform.Rotation = _quaternionRotation; var xfGroup = new Transform3DGroup() { Children = { _scaleTransform, _rotationTransform } }; GeometryModel3D backModel = new GeometryModel3D() { Geometry = simpleQuad, Transform = xfGroup, BackMaterial = backMaterial }; Model3DGroup m3dGroup = new Model3DGroup() { Children = { new DirectionalLight(Colors.White, new Vector3D(0, 0, -1)), new DirectionalLight(Colors.White, new Vector3D(0.1, -0.1, 1)), backModel } }; // Non-interactive Visual3D consisting of the backside, and two lights. ModelVisual3D mv3d = new ModelVisual3D() { Content = m3dGroup }; // Interactive frontside Visual3D Viewport2DVisual3D frontModel = new Viewport2DVisual3D() { Geometry = simpleQuad, Visual = _logicalChild, Material = frontMaterial, Transform = xfGroup }; // Cache the brush in the VP2V3 by setting caching on it. Big perf wins. SetCachingForObject(frontModel); // Scene consists of both the above Visual3D's. _viewport3d = new Viewport3D() { ClipToBounds = false, Children = { mv3d, frontModel } }; UpdateRotation(); return _viewport3d; }
protected override InteractiveVisual3D GetVisual3DRepresentation(object o) { FlickrPhoto photo = (FlickrPhoto)o; // create the visual3D to return PhotoStackViewVisual3D visual3D = new PhotoStackViewVisual3D(photo); // set up the material MaterialGroup material = new MaterialGroup(); DiffuseMaterial interactiveMaterial = new DiffuseMaterial(); interactiveMaterial.SetValue(InteractiveVisual3D.IsInteractiveMaterialProperty, true); material.Children.Add(interactiveMaterial); material.Children.Add(new SpecularMaterial(Brushes.White, 40)); visual3D.Material = material; visual3D.Geometry = meshGeometry; PictureComment xamlRep = GetXamlRepresentation(); visual3D.Visual = xamlRep; xamlRep.pictureVisual.curvatureSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(delegate(object sender, RoutedPropertyChangedEventArgs<double> e) { visual3D.Geometry = CreateGeometry(e.NewValue); }); xamlRep.pictureVisual.closeButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { RemoveItem(photo); }); xamlRep.pictureVisual.geoButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { XmlDocument doc = new XmlDocument(); doc.Load(new StringReader(photo.Info)); XmlNode node = doc.SelectSingleNode("/photo/location"); GeoLocationSelected(Double.Parse(node.Attributes["longitude"].Value), Double.Parse(node.Attributes["latitude"].Value), photo); }); xamlRep.pictureVisual.blogButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { BlogRequested(photo); }); // if there is an authorized user - set it up so they can comment on photos if (Flickr.CurrAuthorizedUser != null) { xamlRep.submitCommentButton.IsEnabled = true; xamlRep.submitCommentButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { Flickr.AsynchPostComments(xamlRep.textBox1.Text, photo, Flickr.CurrAuthorizedUser, Dispatcher, delegate(object result) { if ((bool)result) { Flickr.AsynchGetPhotoComments(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoCommentsReceived(xamlRep, (string)resultData); }); } }); }); } // make an asynch call to flickr to get the photo information we're interested in if (photo != null) { BitmapImage b = new BitmapImage(new Uri(photo.URL_Medium)); if (b.IsDownloading) { // use the small image until the large is ready if (photo.SmallImage != null) { xamlRep.UpdateImage(photo.SmallImage); } b.DownloadCompleted += delegate(object sender, EventArgs e) { xamlRep.UpdateImage(b); ScaleVisual3D(visual3D, xamlRep.Width / (2 * xamlRep.Height)); }; } else { xamlRep.UpdateImage(b); } } // request all sort of information about the photo Flickr.AsynchGetPhotoComments(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoCommentsReceived(xamlRep, (string)resultData); }); if (photo.Info == null) { Flickr.AsynchGetPhotoInfo(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoInfoReceived(xamlRep, (string)resultData); }); } else { PhotoInfoReceived(xamlRep, photo.Info); } ScaleVisual3D(visual3D, xamlRep.Width / (2 * xamlRep.Height)); // return the visual w/o the bitmap yet return visual3D; }