Skip to content

Instantly share code, notes, and snippets.

@dkaraush
Created December 25, 2025 16:15
Show Gist options
  • Select an option

  • Save dkaraush/e229c9b262b49d3c6ebffb302faa14b0 to your computer and use it in GitHub Desktop.

Select an option

Save dkaraush/e229c9b262b49d3c6ebffb302faa14b0 to your computer and use it in GitHub Desktop.
Occlusion Culling Angle Check Helper
public struct AngleRange {
const float HalfPi = MathF.PI * 0.5f;
public float Min, Max;
public AngleRange(int run, int rise) {
Min = MathF.Atan2(rise - 1, run + 1).Clamp(0, HalfPi);
Max = MathF.Atan2(rise + 1, run - 1).Clamp(0, HalfPi);
}
public bool IsEmpty => Max <= Min;
public static AngleRange Full =>
new AngleRange { Min = 0, Max = MathF.PI * 0.5f };
public static AngleRange Intersect(in AngleRange a, in AngleRange b) =>
new AngleRange { Min = MathF.Max(a.Min, b.Min), Max = MathF.Min(a.Max, b.Max) };
public static AngleRange Union(in AngleRange a, in AngleRange b) =>
new() { Min = MathF.Min(a.Min, b.Min), Max = MathF.Max(a.Max, b.Max) };
}
public struct Angles {
public AngleRange XY;
public AngleRange YZ;
public AngleRange XZ;
public Angles(int dx, int dy, int dz) {
dx = dx.Abs();
dy = dy.Abs();
dz = dz.Abs();
XY = new (dx, dy);
YZ = new (dy, dz);
XZ = new (dx, dz);
}
public bool IsEmpty =>
XY.IsEmpty || YZ.IsEmpty || XZ.IsEmpty;
public static Angles Full => new Angles {
XY = AngleRange.Full,
YZ = AngleRange.Full,
XZ = AngleRange.Full
};
public static Angles Intersect(in Angles a, in Angles b) => new Angles {
XY = AngleRange.Intersect(a.XY, b.XY),
YZ = AngleRange.Intersect(a.YZ, b.YZ),
XZ = AngleRange.Intersect(a.XZ, b.XZ),
};
public static Angles Union(in Angles a, in Angles b) => new Angles {
XY = AngleRange.Union(a.XY, b.XY),
YZ = AngleRange.Union(a.YZ, b.YZ),
XZ = AngleRange.Union(a.XZ, b.XZ),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment