| 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 |
} |