/// <summary> /// Transform a Rect3D to a Rect. If this transformation cannot be completed Rect.Empty is returned. /// </summary> /// <param name="rect3D">Input 3D bounding box</param> /// <returns>The 2D bounding box of the projection of these points</returns> public Rect TransformBounds(Rect3D rect3D) { if (_transformBetween2D != null) { return(_transformBetween2D.TransformBounds(MILUtilities.ProjectBounds(ref _projectionTransform, ref rect3D))); } else { return(Rect.Empty); } }
internal override Rect CalculateSubgraphBoundsInnerSpace(bool renderBounds) { Camera camera = Camera; if (camera == null) { return(Rect.Empty); } // // Cache the 3D bounding box for future use. Here we are relying on // the fact that this method is called by PrecomputeContent(), // which is called prior to all usages of _bboxChildrenSubgraph3D. // _bboxChildrenSubgraph3D = ComputeSubgraphBounds3D(); if (_bboxChildrenSubgraph3D.IsEmpty) { // Attempting to project empty bounds will result in NaNs which // which will ruin descendant bounds for the 2D tree. We handle // this explicitly and early exit with the correct answer. return(Rect.Empty); } Rect viewport = Viewport; // Common Case: Viewport3DVisual in a collasped UIElement. if (viewport.IsEmpty) { // Creating a 3D homogenous space to 2D viewport space transform // with an empty rectangle will result in NaNs which ruin the // descendant bounds for the 2D tree. We handle this explicitly // and early exit with the correct answer. // // (See also Windows OS Bugs #1637618) return(Rect.Empty); } double aspectRatio = M3DUtil.GetAspectRatio(viewport.Size); Matrix3D viewProjMatrix = camera.GetViewMatrix() * camera.GetProjectionMatrix(aspectRatio); Rect projectedBounds2D = MILUtilities.ProjectBounds(ref viewProjMatrix, ref _bboxChildrenSubgraph3D); Matrix homoToLocal = M3DUtil.GetHomogeneousToViewportTransform(viewport); MatrixUtil.TransformRect(ref projectedBounds2D, ref homoToLocal); return(projectedBounds2D); }