/// <summary> /// Zooms the camera to the specified rectangle. /// </summary> /// <param name="camera"> /// The camera. /// </param> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="zoomRectangle"> /// The zoom rectangle. /// </param> public static void ZoomToRectangle(this CameraCore camera, ViewportCore viewport, RectangleF zoomRectangle) { if (camera is ProjectionCameraCore pcam) { if (viewport.UnProject(new Vector2(zoomRectangle.Top, zoomRectangle.Left), out var topLeftRay) && viewport.UnProject(new Vector2(zoomRectangle.Top, zoomRectangle.Right), out var topRightRay) && viewport.UnProject( new Vector2( (zoomRectangle.Left + zoomRectangle.Right) * 0.5f, (zoomRectangle.Top + zoomRectangle.Bottom) * 0.5f), out var centerRay)) { var u = topLeftRay.Direction; var v = topRightRay.Direction; var w = centerRay.Direction; u.Normalize(); v.Normalize(); w.Normalize(); if (camera is PerspectiveCameraCore perspectiveCamera) { var distance = pcam.LookDirection.Length(); // option 1: change distance var newDistance = distance * zoomRectangle.Width / viewport.ViewportRectangle.Width; var newLookDirection = (float)newDistance * w; var newPosition = perspectiveCamera.Position + ((distance - (float)newDistance) * w); var newTarget = newPosition + newLookDirection; LookAt(pcam, newTarget, newLookDirection, 200); } else if (camera is OrthographicCameraCore orthographicCamera) { orthographicCamera.Width *= zoomRectangle.Width / viewport.ViewportRectangle.Width; var oldTarget = pcam.Position + pcam.LookDirection; var distance = pcam.LookDirection.Length(); if (centerRay.PlaneIntersection(oldTarget, w, out var newTarget)) { orthographicCamera.LookDirection = w * distance; orthographicCamera.Position = newTarget - orthographicCamera.LookDirection; } } } } }
/// <summary> /// /// </summary> /// <param name="viewport"></param> /// <param name="point2d"></param> /// <returns></returns> public static Ray UnProjectToRay(this ViewportCore viewport, Vector2 point2d) { var r = viewport.UnProject(point2d); return(new Ray(r.Position, r.Direction)); }