/// <summary> /// Viewport3D Constructor /// </summary> public Viewport3D() { _viewport3DVisual = new Viewport3DVisual(); // The value for the Camera property and the Children property on Viewport3D // will also be the value for these properties on the Viewport3DVisual we // create as an internal Visual child. This then will cause these values to // be shared, which will break property inheritance, dynamic resource references // and databinding. To prevent this, we mark the internal // Viewport3DVisual.CanBeInheritanceContext to be false, allowing Camera and // Children to only pick up value context from the Viewport3D (this). _viewport3DVisual.CanBeInheritanceContext = false; this.AddVisualChild(_viewport3DVisual); // NTRAID#Longhorn-1219113-7/11/2005-[....] XamlSerializer does not support RO DPs // // The XamlSerializer currently only serializes locally set properties. To // work around this we intentionally promote our ReadOnly Children // property to locally set. // SetValue(ChildrenPropertyKey, _viewport3DVisual.Children); _viewport3DVisual.SetInheritanceContextForChildren(this); }
private static void ViewportPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Viewport3DVisual owner = ((Viewport3DVisual)d); Debug.Assert(!e.IsASubPropertyChange, "How are we receiving sub property changes from a struct?"); owner.SetFlagsOnAllChannels(true, VisualProxyFlags.Viewport3DVisual_IsViewportDirty | VisualProxyFlags.IsContentDirty); owner.ContentsChanged(/* sender = */ owner, EventArgs.Empty); }
private static void CameraPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Viewport3DVisual owner = ((Viewport3DVisual)d); if (!e.IsASubPropertyChange) { if (e.OldValue != null) { owner.DisconnectAttachedResource( VisualProxyFlags.Viewport3DVisual_IsCameraDirty, ((DUCE.IResource)e.OldValue)); } owner.SetFlagsOnAllChannels(true, VisualProxyFlags.Viewport3DVisual_IsCameraDirty | VisualProxyFlags.IsContentDirty); } owner.ContentsChanged(/* sender = */ owner, EventArgs.Empty); }
/// <summary> /// Computes the transform from world space to the Viewport3DVisual's /// inner 2D space. /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> public static Matrix3D TryWorldToViewportTransform(Viewport3DVisual visual, out bool success) { success = false; Matrix3D result = Matrix3D.Identity; Camera camera = visual.Camera; if (camera == null) { return ZeroMatrix; } Rect viewport = visual.Viewport; if (viewport == Rect.Empty) { return ZeroMatrix; } Transform3D cameraTransform = camera.Transform; if (cameraTransform != null) { Matrix3D m = cameraTransform.Value; if (!m.HasInverse) { return ZeroMatrix; } m.Invert(); result.Append(m); } result.Append(GetViewMatrix(camera)); result.Append(GetProjectionMatrix(camera, MathUtils.GetAspectRatio(viewport.Size))); result.Append(GetHomogeneousToViewportTransform(viewport)); success = true; return result; }
/// <summary> /// Computes the transform from the inner space of the given /// Visual3D to the 2D space of the Viewport3DVisual which /// contains it. /// /// The result will contain the transform of the given visual. /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> /// <param name="visual"></param> /// <param name="success"></param> /// <returns></returns> public static Matrix3D TryTransformTo2DAncestor(DependencyObject visual, out Viewport3DVisual viewport, out bool success) { success = false; Matrix3D to2D = Matrix3D.Identity; viewport = null; if (!(visual is Visual3D)) { throw new ArgumentException("Must be of type Visual3D.", "visual"); } while (visual != null) { if (!(visual is ModelVisual3D)) { break; } Transform3D transform = (Transform3D) visual.GetValue(ModelVisual3D.TransformProperty); if (transform != null) { to2D.Append(transform.Value); } visual = VisualTreeHelper.GetParent(visual); } viewport = visual as Viewport3DVisual; if (viewport == null) { if (visual != null) { // In WPF 3D v1 the only possible configuration is a chain of // ModelVisual3Ds leading up to a Viewport3DVisual. throw new ApplicationException( String.Format("Unsupported type: '{0}'. Expected tree of ModelVisual3Ds leading up to a Viewport3DVisual.", visual.GetType().FullName)); } return ZeroMatrix; } success = true; to2D.Append(MathUtils.TryWorldToViewportTransform(viewport, out success)); if (!success) { return ZeroMatrix; } return to2D; }
public void get_position(object sender, MouseButtonEventArgs e,Viewport3DVisual v) { Point pt = e.GetPosition((UIElement)sender); // Perform the hit test against a given portion of the visual object tree. HitTestResult result = VisualTreeHelper.HitTest(v, pt); if (result != null) { // Perform action on hit visual object. } }
public static Matrix3D GetViewportToWorldTransform(Viewport3DVisual viewport) { Matrix3D matrix = GetWorldToViewportTransform(viewport); if (matrix.HasInverse) { matrix.Invert(); return matrix; } else return ZeroMatrix; }
/// <summary> /// Gets the object space to world space transformation for the given DependencyObject /// </summary> /// <param name="visual">The visual whose world space transform should be found</param> /// <param name="viewport">The Viewport3DVisual the Visual is contained within</param> /// <returns>The world space transformation</returns> private static Matrix3D GetWorldTransformationMatrix(DependencyObject visual, out Viewport3DVisual viewport) { Matrix3D worldTransform = Matrix3D.Identity; viewport = null; if (!(visual is Visual3D)) { throw new ArgumentException("Must be of type Visual3D.", "visual"); } while (visual != null) { if (!(visual is ModelVisual3D)) { break; } Transform3D transform = (Transform3D)visual.GetValue(ModelVisual3D.TransformProperty); if (transform != null) { worldTransform.Append(transform.Value); } visual = VisualTreeHelper.GetParent(visual); } viewport = visual as Viewport3DVisual; if (viewport == null) { if (visual != null) { // In WPF 3D v1 the only possible configuration is a chain of // ModelVisual3Ds leading up to a Viewport3DVisual. throw new ApplicationException( String.Format("Unsupported type: '{0}'. Expected tree of ModelVisual3Ds leading up to a Viewport3DVisual.", visual.GetType().FullName)); } return ZeroMatrix; } return worldTransform; }
/// <summary> /// Computes the transform from the inner space of the given /// Visual3D to the 2D space of the Viewport3DVisual which /// contains it. /// /// The result will contain the transform of the given visual. /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> /// <param name="visual"></param> /// <param name="success"></param> /// <returns></returns> public static Matrix3D TryTransformTo2DAncestor(DependencyObject visual, out Viewport3DVisual viewport, out bool success) { Matrix3D to2D = GetWorldTransformationMatrix(visual, out viewport); to2D.Append(MathUtils.TryWorldToViewportTransform(viewport, out success)); if (!success) { return ZeroMatrix; } return to2D; }
public static Matrix3D GetViewportTransform(Viewport3DVisual vis) { return new Matrix3D(vis.Viewport.Width / 2, 0, 0, 0, 0, -vis.Viewport.Height / 2, 0, 0, 0, 0, 1, 0, vis.Viewport.X + vis.Viewport.Width / 2, vis.Viewport.Y + vis.Viewport.Height / 2, 0, 1); }
/// <summary> /// Computes the transform from world space to the Viewport3DVisual's /// inner 2D space. /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> public static Matrix3D TryWorldToViewportTransform(Viewport3DVisual visual, out bool success) { success = false; Matrix3D result = TryWorldToCameraTransform(visual, out success); if (success) { result.Append(GetProjectionMatrix(visual.Camera, MathUtils.GetAspectRatio(visual.Viewport.Size))); result.Append(GetHomogeneousToViewportTransform(visual.Viewport)); success = true; } return result; }
public static Matrix3D GetCameraTransform(Viewport3DVisual vis) { return CameraInfo.GetTotalTransform(vis.Camera, vis.Viewport.Size.Width / vis.Viewport.Size.Height); }
public static Matrix3D GetTotalTransform(Viewport3DVisual vis) { Matrix3D matx = GetCameraTransform(vis); matx.Append(GetViewportTransform(vis)); return matx; }
/// <summary> /// Computes the transform from world space to camera space /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> public static Matrix3D TryWorldToCameraTransform(Viewport3DVisual visual, out bool success) { success = false; if (visual == null) return ZeroMatrix; Matrix3D result = Matrix3D.Identity; Camera camera = visual.Camera; if (camera == null) { return ZeroMatrix; } Rect viewport = visual.Viewport; if (viewport == Rect.Empty) { return ZeroMatrix; } Transform3D cameraTransform = camera.Transform; if (cameraTransform != null) { Matrix3D m = cameraTransform.Value; if (!m.HasInverse) { return ZeroMatrix; } m.Invert(); result.Append(m); } result.Append(GetViewMatrix(camera)); success = true; return result; }
/// <summary> /// Gets the object space to world space transformation for the given Visual3D /// </summary> /// <param name="visual3DStart">The visual whose world space transform should be found</param> /// <param name="viewport">The containing Viewport3D for the Visual3D</param> /// <returns>The world space transformation</returns> internal static Matrix3D GetWorldTransformationMatrix(Visual3D visual3DStart, out Viewport3DVisual viewport) { DependencyObject dependencyObject = visual3DStart; Matrix3D worldTransform = Matrix3D.Identity; while (dependencyObject != null) { Visual3D visual3D = dependencyObject as Visual3D; // we reached the top if (visual3D == null) { break; } Transform3D transform = (Transform3D)visual3D.GetValue(Visual3D.TransformProperty); if (transform != null) { transform.Append(ref worldTransform); } dependencyObject = VisualTreeHelper.GetParent(dependencyObject); } if (dependencyObject != null) { viewport = (Viewport3DVisual)dependencyObject; } else { viewport = null; } return worldTransform; }
/// <summary> /// Computes the transform from the inner space of the given /// Visual3D to the camera coordinate space /// /// The result will contain the transform of the given visual. /// /// This method can fail if Camera.Transform is non-invertable /// in which case the camera clip planes will be coincident and /// nothing will render. In this case success will be false. /// </summary> /// <param name="visual"></param> /// <param name="success"></param> /// <returns></returns> public static Matrix3D TryTransformToCameraSpace(DependencyObject visual, out Viewport3DVisual viewport, out bool success) { Matrix3D toViewSpace = GetWorldTransformationMatrix(visual, out viewport); toViewSpace.Append(MathUtils.TryWorldToCameraTransform(viewport, out success)); if (!success) { return ZeroMatrix; } return toViewSpace; }
/// <summary> /// Computes the transformation matrix to go from a 3D point in the given Visual3D's coordinate space out in to /// the Viewport3DVisual. /// </summary> internal static bool TryTransformToViewport3DVisual(Visual3D visual3D, out Viewport3DVisual viewport, out Matrix3D matrix) { matrix = GetWorldTransformationMatrix(visual3D, out viewport); if (viewport != null) { matrix *= GetWorldToViewportTransform3D(viewport.Camera, viewport.Viewport); return true; } else { return false; } }
public static Matrix3D GetWorldToViewportTransform(Viewport3DVisual visual) { bool success; Matrix3D result = TryWorldToViewportTransform(visual, out success); if (success) return result; else return ZeroMatrix; }