Ejemplo n.º 1
0
        /// <summary>Tests whether the camera may move further in the current direction</summary>
        public bool PerformRestrictionTest(CameraRestriction Restriction)
        {
            if (CurrentRestriction == CameraRestrictionMode.On)
            {
                Vector3[] p = { Restriction.BottomLeft, Restriction.TopRight };
                Vector2[] r = new Vector2[2];

                for (int j = 0; j < 2; j++)
                {
                    // determine relative world coordinates
                    p[j].Rotate(AbsoluteDirection, AbsoluteUp, AbsoluteSide);
                    double rx = -Math.Tan(Alignment.Yaw) - Alignment.Position.X;
                    double ry = -Math.Tan(Alignment.Pitch) - Alignment.Position.Y;
                    double rz = -Alignment.Position.Z;
                    p[j] += rx * AbsoluteSide + ry * AbsoluteUp + rz * AbsoluteDirection;

                    // determine screen coordinates
                    double ez = AbsoluteDirection.X * p[j].X + AbsoluteDirection.Y * p[j].Y + AbsoluteDirection.Z * p[j].Z;

                    if (ez == 0.0)
                    {
                        return(false);
                    }

                    double ex = AbsoluteSide.X * p[j].X + AbsoluteSide.Y * p[j].Y + AbsoluteSide.Z * p[j].Z;
                    double ey = AbsoluteUp.X * p[j].X + AbsoluteUp.Y * p[j].Y + AbsoluteUp.Z * p[j].Z;
                    r[j].X = ex / (ez * Math.Tan(0.5 * HorizontalViewingAngle));
                    r[j].Y = ey / (ez * Math.Tan(0.5 * VerticalViewingAngle));
                }

                return(r[0].X <= -1.0025 & r[1].X >= 1.0025 & r[0].Y <= -1.0025 & r[1].Y >= 1.0025);
            }
            if (CurrentRestriction == CameraRestrictionMode.Restricted3D)
            {
                Vector3[] p = { Restriction.BottomLeft, Restriction.TopRight };

                for (int j = 0; j < 2; j++)
                {
                    // determine relative world coordinates
                    p[j].Rotate(AbsoluteDirection, AbsoluteUp, AbsoluteSide);
                    double rx = -Math.Tan(Alignment.Yaw) - Alignment.Position.X;
                    double ry = -Math.Tan(Alignment.Pitch) - Alignment.Position.Y;
                    double rz = -Alignment.Position.Z;
                    p[j] += rx * AbsoluteSide + ry * AbsoluteUp + rz * AbsoluteDirection;
                }

                if (AlignmentDirection.Position.X > 0)
                {
                    //moving right
                    if (AbsolutePosition.X >= Restriction.AbsoluteTopRight.X)
                    {
                        return(false);
                    }
                }
                if (AlignmentDirection.Position.X < 0)
                {
                    //moving left
                    if (AbsolutePosition.X <= Restriction.AbsoluteBottomLeft.X)
                    {
                        return(false);
                    }
                }

                if (AlignmentDirection.Position.Y > 0)
                {
                    //moving up
                    if (AbsolutePosition.Y >= Restriction.AbsoluteTopRight.Y)
                    {
                        return(false);
                    }
                }
                if (AlignmentDirection.Position.Y < 0)
                {
                    //moving down
                    if (AbsolutePosition.Y <= Restriction.AbsoluteBottomLeft.Y)
                    {
                        return(false);
                    }
                }

                if (AlignmentDirection.Position.Z > 0)
                {
                    //moving forwards
                    if (AbsolutePosition.Z >= Restriction.AbsoluteTopRight.Z)
                    {
                        return(false);
                    }
                }
                if (AlignmentDirection.Position.Z < 0)
                {
                    //moving back
                    if (AbsolutePosition.Z <= Restriction.AbsoluteBottomLeft.Z)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>Performs progressive adjustments taking into account the specified camera restriction</summary>
        public bool PerformProgressiveAdjustmentForCameraRestriction(ref double Source, double Target, bool Zoom, CameraRestriction Restriction)
        {
            if ((CurrentMode != CameraViewMode.Interior & CurrentMode != CameraViewMode.InteriorLookAhead) | (CurrentRestriction != CameraRestrictionMode.On && CurrentRestriction != CameraRestrictionMode.Restricted3D))
            {
                Source = Target;
                return(true);
            }

            double    best      = Source;
            const int Precision = 8;
            double    a         = Source;
            double    b         = Target;

            Source = Target;
            if (Zoom)
            {
                ApplyZoom();
            }
            if (PerformRestrictionTest(Restriction))
            {
                return(true);
            }

            double x = 0.5 * (a + b);
            bool   q = true;

            for (int i = 0; i < Precision; i++)
            {
#pragma warning disable IDE0059 //IDE is wrong, best may never be updated if q is never true
                Source = x;
#pragma warning restore IDE0059
                if (Zoom)
                {
                    ApplyZoom();
                }
                q = PerformRestrictionTest(Restriction);
                if (q)
                {
                    a    = x;
                    best = x;
                }
                else
                {
                    b = x;
                }

                x = 0.5 * (a + b);
            }

            Source = best;
            if (Zoom)
            {
                ApplyZoom();
            }
            return(q);
        }