public IntVector3 ToIntVector3() { return(new IntVector3(MyMath.Round(this.X), MyMath.Round(this.Y), MyMath.Round(this.Z))); }
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))); }