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