Beispiel #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);
                    }
                }
            }
        }
Beispiel #2
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);
 }
Beispiel #3
0
        /// <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;
                    }
                }
            }
        }
Beispiel #4
0
        /// <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);
            }
        }
Beispiel #5
0
        private static void NegativeNearClippingHelper(double near_dist, double far_dist, ViewportInfo vp)
        {
            double n = near_dist;
            double f = far_dist;

            double min_near_dist = 0.000100;

            if (double.IsNaN(min_near_dist) || min_near_dist < 1.0e-6)
            {
                min_near_dist = 1.0e-6;
            }
            if (vp.IsParallelProjection && n < min_near_dist)
            {
                // move camera back in ortho projection so everything shows
                double d = 1.00001 * min_near_dist - n;
                if (d < 0.005)
                {
                    d = 0.005;
                }
                n += d;
                f += d;
                if (double.IsNaN(d) ||
                    d <= 0.0 ||
                    double.IsNaN(n) ||
                    double.IsNaN(f) ||
                    n < min_near_dist ||
                    f <= n
                    )
                {
                    // Just give up but ... refuse to accept garbage
                    n = 0.005;
                    f = 1000.0;
                }
                else
                {
                    Rhino.Geometry.Point3d new_loc = vp.CameraLocation + d * vp.CameraZ;
                    vp.SetCameraLocation(new_loc);
                }
                near_dist = n;
                far_dist  = f;
            }
        }
Beispiel #6
0
        /// <summary>
        /// LateralPan of a viewport between two points
        /// </summary>
        public static void LateralPan(this ViewportInfo viewport, CGPoint fromPoint, CGPoint toPoint, bool flipX, bool flipY)
        {
            double deltaX, deltaY, s;

            Rhino.Geometry.Transform s2c          = viewport.GetXform(CoordinateSystem.Screen, CoordinateSystem.Clip);
            Rhino.Geometry.Point3d   screenPoint0 = new Rhino.Geometry.Point3d(fromPoint.X, fromPoint.Y, 0.0);
            Rhino.Geometry.Point3d   screenPoint1 = new Rhino.Geometry.Point3d(toPoint.X, toPoint.Y, 0.0);
            Rhino.Geometry.Point3d   clipPoint0   = s2c * screenPoint0;
            Rhino.Geometry.Point3d   clipPoint1   = s2c * screenPoint1;
            deltaX  = 0.5 * (clipPoint1.X - clipPoint0.X);
            deltaY  = 0.5 * (clipPoint1.Y - clipPoint0.Y);
            deltaX *= (viewport.FrustumRight - viewport.FrustumLeft);
            deltaY *= (viewport.FrustumBottom - viewport.FrustumTop);
            if (viewport.IsPerspectiveProjection)
            {
                s       = viewport.TargetPoint.DistanceTo(viewport.CameraLocation) / viewport.FrustumNear;
                deltaX *= flipX ? -s : s;
                deltaY *= flipY ? -s : s;
            }
            Rhino.Geometry.Vector3d dollyVector = (deltaX * viewport.CameraX) + (deltaY * viewport.CameraY);
            viewport.TargetPoint = viewport.TargetPoint - dollyVector;
            viewport.SetCameraLocation(viewport.CameraLocation - dollyVector);
        }
Beispiel #7
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);
        }
Beispiel #8
0
        /// <summary>
        /// <para>Moves the Camera in a viewport toward a fixed point</para>
        /// </summary>
        public static bool Move(this ViewportInfo viewport, CGSize viewSize, double magnifcationFactor, CGPoint fixedScreenPoint)
        {
            if (viewport.IsCameraLocationLocked)
            {
                return(false);
            }

            var screenWidth  = viewSize.Width;
            var 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 frustumNear   = viewport.FrustumNear;
                double frustumWidth  = viewport.FrustumWidth;
                double frustumHeight = viewport.FrustumHeight;
                double d             = 0.0;

                // dolly camera location and the target location...
                if (viewport.IsPerspectiveProjection)
                {
                    const double miniumumTargetDistance = 0.000001;

                    var cameraZ        = viewport.CameraZ;
                    var cameraLocation = viewport.CameraLocation;
                    var target         = viewport.TargetPoint;
                    var v0             = target - cameraLocation;

                    double targetDistance = (cameraLocation - target) * cameraZ;
                    if (targetDistance >= 0.0)
                    {
                        double delta = (1.0 - (1.0 / magnifcationFactor)) * targetDistance;

                        if (targetDistance - delta > miniumumTargetDistance)
                        {
                            v0.Unitize();

                            var l           = delta * v0;
                            var newLocation = cameraLocation + l;
                            var newTarget   = target + l;

                            viewport.SetTarget(newTarget, newLocation, Rhino.Geometry.Vector3d.ZAxis);

                            if (!fixedScreenPoint.IsEmpty)
                            {
                                d              = (targetDistance / 2) / frustumNear;
                                frustumWidth  *= d;
                                frustumHeight *= d;
                                d              = ((targetDistance / 2) - delta) / (targetDistance / 2);
                            }
                        }
                    }
                }

                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);
        }