/// <summary> /// Find the Perspective viewport in the 3dm file and sets up the default view. /// </summary> public void LoadCamera() { if (App.Manager.CurrentModel == null) { return; } Camera = new ViewportInfo(); bool cameraIsInitialized = false; int viewCount = App.Manager.CurrentModel.ModelFile.Views.Count; // find first perspective viewport projection in file if (viewCount > 0) { foreach (var view in App.Manager.CurrentModel.ModelFile.Views) { if (view.Viewport.IsPerspectiveProjection) { cameraIsInitialized = true; Camera = view.Viewport; Camera.TargetPoint = view.Viewport.TargetPoint; Camera.SetScreenPort(0, (int)View.Bounds.Size.Width, 0, (int)View.Bounds.Size.Height, 1, 1000); Camera.FrustumAspect = Camera.ScreenPortAspect; Camera.SetFrustumNearFar(App.Manager.CurrentModel.BBox); break; } } } // If there isn't one, then cook up a viewport from scratch... if (!cameraIsInitialized) { Camera.SetScreenPort(0, (int)View.Bounds.Size.Width, 0, (int)View.Bounds.Size.Height, 1, 1000); Camera.TargetPoint = new Rhino.Geometry.Point3d(0, 0, 0); var plane = new Rhino.Geometry.Plane(Rhino.Geometry.Point3d.Origin, new Rhino.Geometry.Vector3d(-1, -1, -1)); Camera.SetCameraLocation(new Rhino.Geometry.Point3d(10, 10, 10)); var dir = new Rhino.Geometry.Vector3d(-1, -1, -1); dir.Unitize(); Camera.SetCameraDirection(dir); Camera.SetCameraUp(plane.YAxis); Camera.SetFrustum(-1, 1, -1, 1, 0.1, 1000); Camera.FrustumAspect = Camera.ScreenPortAspect; Camera.IsPerspectiveProjection = true; Camera.Camera35mmLensLength = 50; if (App.Manager.CurrentModel != null) { if (App.Manager.CurrentModel.AllMeshes != null) { Camera.DollyExtents(App.Manager.CurrentModel.AllMeshes, 1.0); } } } }
/// <summary> /// Rotates a viewport about an axis relative to a center point /// </summary> public static void RotateView(this ViewportInfo viewport, Rhino.Geometry.Vector3d axis, Rhino.Geometry.Point3d center, double angle) { Rhino.Geometry.Point3d cameraLocation = viewport.CameraLocation; Rhino.Geometry.Vector3d cameraY = viewport.CameraY; Rhino.Geometry.Vector3d cameraZ = viewport.CameraZ; Rhino.Geometry.Transform rotation = Rhino.Geometry.Transform.Rotation(angle, axis, center); cameraLocation = rotation * cameraLocation; cameraY = rotation * cameraY; cameraZ = -(rotation * cameraZ); viewport.SetCameraLocation(cameraLocation); viewport.SetCameraDirection(cameraZ); viewport.SetCameraUp(cameraY); }
/// <summary> /// Sets the viewport's camera location, target and up vector /// </summary> public static void SetTarget(this ViewportInfo viewport, Rhino.Geometry.Point3d targetLocation, Rhino.Geometry.Point3d cameraLocation, Rhino.Geometry.Vector3d cameraUp) { Rhino.Geometry.Vector3d cameraDirection = targetLocation - cameraLocation; cameraDirection.Unitize(); if (!viewport.CameraDirection.IsTiny()) { Rhino.Geometry.Vector3d cameraDirection0 = -viewport.CameraZ; Rhino.Geometry.Vector3d cameraY = viewport.CameraY; const double tiltAngle = 0; viewport.SetCameraLocation(cameraLocation); viewport.SetCameraDirection(cameraDirection); bool didSetTarget = false; didSetTarget = viewport.SetCameraUp(cameraUp); if (!didSetTarget) { didSetTarget = viewport.SetCameraUp(cameraY); cameraUp = cameraY; } if (!didSetTarget) { Rhino.Geometry.Vector3d rotationAxis = Rhino.Geometry.Vector3d.CrossProduct(cameraDirection0, cameraDirection); double sinAngle = rotationAxis.Length; double cosAngle = cameraDirection0 * cameraDirection; Rhino.Geometry.Transform rot = Rhino.Geometry.Transform.Rotation(sinAngle, cosAngle, rotationAxis, Rhino.Geometry.Point3d.Origin); cameraUp = rot * cameraY; didSetTarget = viewport.SetCameraUp(cameraUp); } if (didSetTarget) { // Apply tilt angle to new camera and target location if (Math.Abs(tiltAngle) > 1.0e-6) { Rhino.Geometry.Transform rot = Rhino.Geometry.Transform.Rotation(tiltAngle, -cameraDirection0, cameraLocation); cameraUp = rot * cameraUp; didSetTarget = viewport.SetCameraUp(cameraUp); } if (didSetTarget) { viewport.TargetPoint = targetLocation; } } } }
/// <summary> /// Rotates the viewport around an axis by an angle /// </summary> public static void RotateCameraAround(this ViewportInfo viewport, Rhino.Geometry.Vector3d axis, double angle) { Rhino.Geometry.Point3d cameraLocation = viewport.CameraLocation; double targetDistance = (cameraLocation - viewport.TargetPoint) * viewport.CameraZ; Rhino.Geometry.Transform rotationTransform = Rhino.Geometry.Transform.Rotation(angle, axis, cameraLocation); Rhino.Geometry.Vector3d cameraDirection = -(rotationTransform * viewport.CameraZ); if (cameraDirection.Z >= -0.99 && cameraDirection.Z <= 0.99) // avoid gimbal "lock" { Rhino.Geometry.Point3d target = cameraLocation + targetDistance * cameraDirection; viewport.TargetPoint = target; viewport.SetCameraLocation(cameraLocation); viewport.SetCameraDirection(cameraDirection); viewport.SetCameraUp(Rhino.Geometry.Vector3d.ZAxis); } }