| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace Oni | 
 
 
 
 
 | 5 | { | 
 
 
 
 
 | 6 | internal struct BoundingBox : IEquatable<BoundingBox> | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | public Vector3 Min; | 
 
 
 
 
 | 9 | public Vector3 Max; | 
 
 
 
 
 | 10 |  | 
 
 
 
 
 | 11 | public BoundingBox(Vector3 min, Vector3 max) | 
 
 
 
 
 | 12 | { | 
 
 
 
 
 | 13 | Min = min; | 
 
 
 
 
 | 14 | Max = max; | 
 
 
 
 
 | 15 | } | 
 
 
 
 
 | 16 |  | 
 
 
 
 
 | 17 | public static BoundingBox CreateFromSphere(BoundingSphere sphere) | 
 
 
 
 
 | 18 | { | 
 
 
 
 
 | 19 | var radius = new Vector3(sphere.Radius); | 
 
 
 
 
 | 20 |  | 
 
 
 
 
 | 21 | return new BoundingBox(sphere.Center - radius, sphere.Center + radius); | 
 
 
 
 
 | 22 | } | 
 
 
 
 
 | 23 |  | 
 
 
 
 
 | 24 | public static BoundingBox CreateFromPoints(IEnumerable<Vector3> points) | 
 
 
 
 
 | 25 | { | 
 
 
 
 
 | 26 | var min = new Vector3(float.MaxValue); | 
 
 
 
 
 | 27 | var max = new Vector3(float.MinValue); | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | foreach (var point in points) | 
 
 
 
 
 | 30 | { | 
 
 
 
 
 | 31 | var p = point; | 
 
 
 
 
 | 32 |  | 
 
 
 
 
 | 33 | Vector3.Min(ref min, ref p, out min); | 
 
 
 
 
 | 34 | Vector3.Max(ref max, ref p, out max); | 
 
 
 
 
 | 35 | } | 
 
 
 
 
 | 36 |  | 
 
 
 
 
 | 37 | return new BoundingBox(min, max); | 
 
 
 
 
 | 38 | } | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | public bool Contains(Vector3 point) => | 
 
 
 
 
 | 41 | point.X >= Min.X && point.X <= Max.X | 
 
 
 
 
 | 42 | && point.Y >= Min.Y && point.Y <= Max.Y | 
 
 
 
 
 | 43 | && point.Z >= Min.Z && point.Z <= Max.Z; | 
 
 
 
 
 | 44 |  | 
 
 
 
 
 | 45 | public bool Contains(BoundingBox box) => | 
 
 
 
 
 | 46 | Min.X <= box.Min.X && box.Max.X <= Max.X | 
 
 
 
 
 | 47 | && Min.Y <= box.Min.Y && box.Max.Y <= Max.Y | 
 
 
 
 
 | 48 | && Min.Z <= box.Min.Z && box.Max.Z <= Max.Z; | 
 
 
 
 
 | 49 |  | 
 
 
 
 
 | 50 | public bool Intersects(BoundingBox box) => | 
 
 
 
 
 | 51 | Max.X >= box.Min.X && Min.X <= box.Max.X | 
 
 
 
 
 | 52 | && Max.Y >= box.Min.Y && Min.Y <= box.Max.Y | 
 
 
 
 
 | 53 | && Max.Z >= box.Min.Z && Min.Z <= box.Max.Z; | 
 
 
 
 
 | 54 |  | 
 
 
 
 
 | 55 | public bool Intersects(Plane plane) | 
 
 
 
 
 | 56 | { | 
 
 
 
 
 | 57 | Vector3 v0, v1; | 
 
 
 
 
 | 58 |  | 
 
 
 
 
 | 59 | v0.X = (plane.Normal.X >= 0.0f) ? Max.X : Min.X; | 
 
 
 
 
 | 60 | v1.X = (plane.Normal.X >= 0.0f) ? Min.X : Max.X; | 
 
 
 
 
 | 61 |  | 
 
 
 
 
 | 62 | v0.Y = (plane.Normal.Y >= 0.0f) ? Max.Y : Min.Y; | 
 
 
 
 
 | 63 | v1.Y = (plane.Normal.Y >= 0.0f) ? Min.Y : Max.Y; | 
 
 
 
 
 | 64 |  | 
 
 
 
 
 | 65 | v0.Z = (plane.Normal.Z >= 0.0f) ? Max.Z : Min.Z; | 
 
 
 
 
 | 66 | v1.Z = (plane.Normal.Z >= 0.0f) ? Min.Z : Max.Z; | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | return plane.Normal.Dot(ref v1) <= -plane.D | 
 
 
 
 
 | 69 | && plane.Normal.Dot(ref v0) >= -plane.D; | 
 
 
 
 
 | 70 | } | 
 
 
 
 
 | 71 |  | 
 
 
 
 
 | 72 | public Vector3[] GetCorners() => new[] | 
 
 
 
 
 | 73 | { | 
 
 
 
 
 | 74 | new Vector3(Min.X, Max.Y, Max.Z), | 
 
 
 
 
 | 75 | new Vector3(Max.X, Max.Y, Max.Z), | 
 
 
 
 
 | 76 | new Vector3(Max.X, Min.Y, Max.Z), | 
 
 
 
 
 | 77 | new Vector3(Min.X, Min.Y, Max.Z), | 
 
 
 
 
 | 78 | new Vector3(Min.X, Max.Y, Min.Z), | 
 
 
 
 
 | 79 | new Vector3(Max.X, Max.Y, Min.Z), | 
 
 
 
 
 | 80 | new Vector3(Max.X, Min.Y, Min.Z), | 
 
 
 
 
 | 81 | new Vector3(Min.X, Min.Y, Min.Z) | 
 
 
 
 
 | 82 | }; | 
 
 
 
 
 | 83 |  | 
 
 
 
 
 | 84 | public static bool operator ==(BoundingBox b1, BoundingBox b2) => b1.Min == b2.Min && b1.Max == b2.Max; | 
 
 
 
 
 | 85 | public static bool operator !=(BoundingBox b1, BoundingBox b2) => b1.Min != b2.Min || b1.Max != b2.Max; | 
 
 
 
 
 | 86 |  | 
 
 
 
 
 | 87 | public bool Equals(BoundingBox other) => Min == other.Min && Max == other.Max; | 
 
 
 
 
 | 88 |  | 
 
 
 
 
 | 89 | public override bool Equals(object obj) => obj is BoundingBox && Equals((BoundingBox)obj); | 
 
 
 
 
 | 90 | public override int GetHashCode() => Min.GetHashCode() ^ Max.GetHashCode(); | 
 
 
 
 
 | 91 |  | 
 
 
 
 
 | 92 | public override string ToString() => $"{{{Min} {Max}}}"; | 
 
 
 
 
 | 93 |  | 
 
 
 
 
 | 94 | public float Volume() | 
 
 
 
 
 | 95 | { | 
 
 
 
 
 | 96 | Vector3 size = Max - Min; | 
 
 
 
 
 | 97 | return size.X * size.Y * size.Z; | 
 
 
 
 
 | 98 | } | 
 
 
 
 
 | 99 |  | 
 
 
 
 
 | 100 | public void Inflate(Vector3 v) | 
 
 
 
 
 | 101 | { | 
 
 
 
 
 | 102 | Min -= v; | 
 
 
 
 
 | 103 | Max += v; | 
 
 
 
 
 | 104 | } | 
 
 
 
 
 | 105 |  | 
 
 
 
 
 | 106 | public float Height => Max.Y - Min.Y; | 
 
 
 
 
 | 107 | public float Width => Max.X - Min.X; | 
 
 
 
 
 | 108 | public float Depth => Max.Z - Min.Z; | 
 
 
 
 
 | 109 |  | 
 
 
 
 
 | 110 | public Vector3 Size => Max - Min; | 
 
 
 
 
 | 111 | } | 
 
 
 
 
 | 112 | } |