예제 #1
0
        /// <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);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// <para>Magnify/Zoom the Camera in a viewport</para>
        /// <para>method =</para>
        /// <para>0 performs a "dolly" magnification by moving the
        ///   camera along the camera direction vector so that
        ///   the amount of the screen subtended by an object
        ///   changes.</para>
        /// <para>1 performs a "zoom" magnification by adjusting the
        ///   "lens" angle</para>
        /// </summary>
        public static bool Magnify(this ViewportInfo viewport, Size viewSize, double magnifcationFactor, int method, System.Drawing.PointF fixedScreenPoint)
        {
            if (viewport.IsCameraLocationLocked)
            {
                return(false);
            }

            int screenWidth  = viewSize.Width;
            int screenHeight = viewSize.Height;

            if (1 > screenWidth || 1 > screenHeight)
            {
                return(false);
            }

            // move camera toward target to magnify
            if (magnifcationFactor > 0)
            {
                // if the screen point is not in the viewport, then ignore it.
                if (!fixedScreenPoint.IsEmpty)
                {
                    if (fixedScreenPoint.X <= 0 || fixedScreenPoint.X >= screenWidth - 1 || fixedScreenPoint.Y <= 0 || fixedScreenPoint.Y >= screenHeight - 1)
                    {
                        fixedScreenPoint.X = 0;
                        fixedScreenPoint.Y = 0;
                    }
                }
                double frustumLeft   = viewport.FrustumLeft;
                double frustumRight  = viewport.FrustumRight;
                double frustumBottom = viewport.FrustumBottom;
                double frustumTop    = viewport.FrustumTop;
                double frustumNear   = viewport.FrustumNear;
                double frustumFar    = viewport.FrustumFar;
                double frustumWidth  = viewport.FrustumWidth;
                double frustumHeight = viewport.FrustumHeight;
                double d             = 0.0;

                // dolly camera towards target point...
                if (viewport.IsPerspectiveProjection && method == 0)
                {
                    const double miniumumTargetDistance = 0.000001;
                    var          cameraZ        = viewport.CameraZ;
                    var          cameraLocation = viewport.CameraLocation;
                    var          target         = viewport.TargetPoint;
                    double       targetDistance = (cameraLocation - target) * cameraZ;
                    if (targetDistance >= 0.0)
                    {
                        double delta = (1.0 - (1.0 / magnifcationFactor)) * targetDistance;
                        if (targetDistance - delta > miniumumTargetDistance)
                        {
                            cameraLocation = cameraLocation - (delta * cameraZ);
                            viewport.SetCameraLocation(cameraLocation);
                            if (!fixedScreenPoint.IsEmpty)
                            {
                                d              = targetDistance / viewport.FrustumNear;
                                frustumWidth  *= d;
                                frustumHeight *= d;
                                d              = (targetDistance - delta) / targetDistance;
                            }
                        }
                    }
                }
                if (method == 1)
                {
                    // parallel proj or "true" zoom
                    // apply magnification to frustum
                    d              = 1.0 / magnifcationFactor;
                    frustumLeft   *= d;
                    frustumRight  *= d;
                    frustumBottom *= d;
                    frustumTop    *= d;
                    viewport.SetFrustum(frustumLeft, frustumRight, frustumBottom, frustumTop, frustumNear, frustumFar);
                }

                if (!fixedScreenPoint.IsEmpty && Math.Abs(d) > Double.Epsilon)
                {
                    // lateral dolly to keep fixed_screen_point in same location on screen
                    Rhino.Geometry.Vector3d scale = new Rhino.Geometry.Vector3d(1.0, 1.0, 1.0);
                    scale.X = viewport.ViewScale.Width;
                    scale.Y = viewport.ViewScale.Height;
                    double fx = ((double)fixedScreenPoint.X / (double)screenWidth);
                    double fy = ((double)fixedScreenPoint.Y / (double)screenHeight);
                    double dx = ((0.5 - fx) * (1.0 - d) * frustumWidth) / scale.X;
                    double dy = ((fy - 0.5) * (1.0 - d) * frustumHeight) / scale.Y;
                    Rhino.Geometry.Vector3d dollyVector = dx * viewport.CameraX + dy * viewport.CameraY;
                    var cameraLocation = viewport.CameraLocation;
                    var target         = viewport.TargetPoint;
                    viewport.TargetPoint = target - dollyVector;
                    viewport.SetCameraLocation(cameraLocation - dollyVector);
                }
            }
            return(true);
        }