public IntVector3 ToIntVector3()
 {
     return(new IntVector3(MyMath.Round(this.X), MyMath.Round(this.Y), MyMath.Round(this.Z)));
 }
Exemple #2
0
        static void Calculate(ref SCRData data, int startColumn, int octant, double startSlope, double endSlope, int id)
        {
            //Debug.Print("{4}{0}: Calc, start col {3}, slope {1} -> {2}", id, startSlope, endSlope, startColumn, new string(' ', (id - 1) * 4));

            if (startSlope > endSlope)
            {
                return;
            }

            int maxX;

            switch (octant)
            {
            case 0:
            case 7:
                maxX = Math.Min(data.VisionRange, data.MapSize.Width - data.ViewerLocation.X - 1);
                break;

            case 1:
            case 2:
                maxX = Math.Min(data.VisionRange, data.MapSize.Height - data.ViewerLocation.Y - 1);
                break;

            case 3:
            case 4:
                maxX = Math.Min(data.VisionRange, data.ViewerLocation.X);
                break;

            case 5:
            case 6:
                maxX = Math.Min(data.VisionRange, data.ViewerLocation.Y);
                break;

            default:
                throw new Exception();
            }

            for (int x = startColumn; x <= maxX; ++x)
            {
                bool   currentlyBlocked = false;
                double newStart         = 0;

                int lowY  = MyMath.RoundTowards(startSlope * x);
                int highY = MyMath.RoundAway(endSlope * x);

                switch (octant)
                {
                case 0:
                case 3:
                    highY = Math.Min(highY, data.MapSize.Height - data.ViewerLocation.Y - 1);
                    break;

                case 1:
                case 6:
                    highY = Math.Min(highY, data.MapSize.Width - data.ViewerLocation.X - 1);
                    break;

                case 7:
                case 4:
                    highY = Math.Min(highY, data.ViewerLocation.Y);
                    break;

                case 2:
                case 5:
                    highY = Math.Min(highY, data.ViewerLocation.X);
                    break;

                default:
                    throw new Exception();
                }

                //Debug.Print("{0}{1}: col {2} lowY {3}, highY {4}", new string(' ', (id - 1) * 4), id, x, lowY, highY);

                for (int y = lowY; y <= highY; ++y)
                {
                    IntVector2 translatedLocation = OctantTranslate(new IntVector2(x, y), octant);
                    IntVector2 mapLocation        = translatedLocation.Offset(data.ViewerLocation.X, data.ViewerLocation.Y);

                    Debug.Assert(data.MapSize.Contains(mapLocation));

                    if (x * x + y * y > data.VisionRangeSquared)
                    {
                        data.VisibilityMap[translatedLocation] = false;
                        continue;
                    }

                    double lowerSlope = (y - 0.5) / (x + 0.5);
                    double upperSlope = (y + 0.5) / (x - 0.5);

#if PERMISSIVE
                    if (upperSlope < startSlope || lowerSlope > endSlope)
                    {
                        //Debug.Print("{0}{1}: {2},{3}   center {4:F2} ouside arc", new string(' ', (id - 1) * 4), id, x, y, centerSlope);
                        continue;
                    }

                    bool tileBlocked = data.BlockerDelegate(mapLocation);
#elif MEDIUM_STRICT
                    double centerSlope = (double)y / x;

                    bool tileBlocked = data.BlockerDelegate(mapLocation);

                    if (!tileBlocked && (centerSlope < startSlope || centerSlope > endSlope))
                    {
                        //Debug.Print("{0}{1}: {2},{3}   center {4:F2} ouside arc", new string(' ', (id - 1) * 4), id, x, y, centerSlope);
                        continue;
                    }
#else
#error no mode defined
#endif
                    //Debug.Print("{0}{1}: {2},{3}   center {4:F2} visible", new string(' ', (id - 1) * 4), id, x, y, centerSlope);

                    data.VisibilityMap[translatedLocation] = true;

                    if (currentlyBlocked)
                    {
                        if (tileBlocked)
                        {
                            newStart = upperSlope;
                            continue;
                        }
                        else
                        {
                            currentlyBlocked = false;
                            startSlope       = newStart;
                            //Debug.Print("{0}{1}: {2},{3}  new startSlope {4:F2}", new string(' ', (id - 1) * 4), id, x, y, startSlope);
                        }
                    }
                    else
                    {
                        if (tileBlocked)
                        {
                            currentlyBlocked = true;
                            newStart         = upperSlope;

                            Calculate(ref data, x + 1, octant, startSlope, lowerSlope, id + 1);
                        }
                    }
                }

                if (currentlyBlocked)
                {
                    break;
                }
            }
        }
 public DoubleVector3 Round()
 {
     return(new DoubleVector3(MyMath.Round(this.X), MyMath.Round(this.Y), MyMath.Round(this.Z)));
 }