TrueSync
TSBBox.cs
1 /* Copyright (C) <2009-2011> <Thorben Linneweber, Jitter Physics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 * 2. Altered source versions must be plainly marked as such, and must not be
16 * misrepresented as being the original software.
17 * 3. This notice may not be removed or altered from any source distribution.
18 */
19 
20 namespace TrueSync
21 {
25  public struct TSBBox
26  {
30  public enum ContainmentType
31  {
35  Disjoint,
39  Contains,
43  Intersects
44  }
45 
49  public TSVector min;
50 
54  public TSVector max;
55 
59  public static readonly TSBBox LargeBox;
60 
64  public static readonly TSBBox SmallBox;
65 
66  static TSBBox()
67  {
68  LargeBox.min = new TSVector(FP.MinValue);
69  LargeBox.max = new TSVector(FP.MaxValue);
70  SmallBox.min = new TSVector(FP.MaxValue);
71  SmallBox.max = new TSVector(FP.MinValue);
72  }
73 
79  public TSBBox(TSVector min, TSVector max)
80  {
81  this.min = min;
82  this.max = max;
83  }
84 
91  internal void InverseTransform(ref TSVector position, ref TSMatrix orientation)
92  {
93  TSVector.Subtract(ref max, ref position, out max);
94  TSVector.Subtract(ref min, ref position, out min);
95 
96  TSVector center;
97  TSVector.Add(ref max, ref min, out center);
98  center.x *= FP.Half; center.y *= FP.Half; center.z *= FP.Half;
99 
100  TSVector halfExtents;
101  TSVector.Subtract(ref max, ref min, out halfExtents);
102  halfExtents.x *= FP.Half; halfExtents.y *= FP.Half; halfExtents.z *= FP.Half;
103 
104  TSVector.TransposedTransform(ref center, ref orientation, out center);
105 
106  TSMatrix abs; TSMath.Absolute(ref orientation, out abs);
107  TSVector.TransposedTransform(ref halfExtents, ref abs, out halfExtents);
108 
109  TSVector.Add(ref center, ref halfExtents, out max);
110  TSVector.Subtract(ref center, ref halfExtents, out min);
111  }
112 
113  public void Transform(ref TSMatrix orientation)
114  {
115  TSVector halfExtents = FP.Half * (max - min);
116  TSVector center = FP.Half * (max + min);
117 
118  TSVector.Transform(ref center, ref orientation, out center);
119 
120  TSMatrix abs; TSMath.Absolute(ref orientation, out abs);
121  TSVector.Transform(ref halfExtents, ref abs, out halfExtents);
122 
123  max = center + halfExtents;
124  min = center - halfExtents;
125  }
126 
132  #region public Ray/Segment Intersection
133 
134  private bool Intersect1D(FP start, FP dir, FP min, FP max,
135  ref FP enter,ref FP exit)
136  {
137  if (dir * dir < TSMath.Epsilon * TSMath.Epsilon) return (start >= min && start <= max);
138 
139  FP t0 = (min - start) / dir;
140  FP t1 = (max - start) / dir;
141 
142  if (t0 > t1) { FP tmp = t0; t0 = t1; t1 = tmp; }
143 
144  if (t0 > exit || t1 < enter) return false;
145 
146  if (t0 > enter) enter = t0;
147  if (t1 < exit) exit = t1;
148  return true;
149  }
150 
151 
152  public bool SegmentIntersect(ref TSVector origin,ref TSVector direction)
153  {
154  FP enter = FP.Zero, exit = FP.One;
155 
156  if (!Intersect1D(origin.x, direction.x, min.x, max.x,ref enter,ref exit))
157  return false;
158 
159  if (!Intersect1D(origin.y, direction.y, min.y, max.y, ref enter, ref exit))
160  return false;
161 
162  if (!Intersect1D(origin.z, direction.z, min.z, max.z,ref enter,ref exit))
163  return false;
164 
165  return true;
166  }
167 
168  public bool RayIntersect(ref TSVector origin, ref TSVector direction)
169  {
170  FP enter = FP.Zero, exit = FP.MaxValue;
171 
172  if (!Intersect1D(origin.x, direction.x, min.x, max.x, ref enter, ref exit))
173  return false;
174 
175  if (!Intersect1D(origin.y, direction.y, min.y, max.y, ref enter, ref exit))
176  return false;
177 
178  if (!Intersect1D(origin.z, direction.z, min.z, max.z, ref enter, ref exit))
179  return false;
180 
181  return true;
182  }
183 
184  public bool SegmentIntersect(TSVector origin, TSVector direction)
185  {
186  return SegmentIntersect(ref origin, ref direction);
187  }
188 
189  public bool RayIntersect(TSVector origin, TSVector direction)
190  {
191  return RayIntersect(ref origin, ref direction);
192  }
193 
200  {
201  return this.Contains(ref point);
202  }
203 
211  {
212  return ((((this.min.x <= point.x) && (point.x <= this.max.x)) &&
213  ((this.min.y <= point.y) && (point.y <= this.max.y))) &&
214  ((this.min.z <= point.z) && (point.z <= this.max.z))) ? ContainmentType.Contains : ContainmentType.Disjoint;
215  }
216 
217  #endregion
218 
223  #region public void GetCorners(JVector[] corners)
224 
225  public void GetCorners(TSVector[] corners)
226  {
227  corners[0].Set(this.min.x, this.max.y, this.max.z);
228  corners[1].Set(this.max.x, this.max.y, this.max.z);
229  corners[2].Set(this.max.x, this.min.y, this.max.z);
230  corners[3].Set(this.min.x, this.min.y, this.max.z);
231  corners[4].Set(this.min.x, this.max.y, this.min.z);
232  corners[5].Set(this.max.x, this.max.y, this.min.z);
233  corners[6].Set(this.max.x, this.min.y, this.min.z);
234  corners[7].Set(this.min.x, this.min.y, this.min.z);
235  }
236 
237  #endregion
238 
239 
240  public void AddPoint(TSVector point)
241  {
242  AddPoint(ref point);
243  }
244 
245  public void AddPoint(ref TSVector point)
246  {
247  TSVector.Max(ref this.max, ref point, out this.max);
248  TSVector.Min(ref this.min, ref point, out this.min);
249  }
250 
257  #region public static JBBox CreateFromPoints(JVector[] points)
258 
259  public static TSBBox CreateFromPoints(TSVector[] points)
260  {
261  TSVector vector3 = new TSVector(FP.MaxValue);
262  TSVector vector2 = new TSVector(FP.MinValue);
263 
264  for (int i = 0; i < points.Length; i++)
265  {
266  TSVector.Min(ref vector3, ref points[i], out vector3);
267  TSVector.Max(ref vector2, ref points[i], out vector2);
268  }
269  return new TSBBox(vector3, vector2);
270  }
271 
272  #endregion
273 
280  #region public ContainmentType Contains(JBBox box)
281 
283  {
284  return this.Contains(ref box);
285  }
286 
294  {
295  ContainmentType result = ContainmentType.Disjoint;
296  if ((((this.max.x >= box.min.x) && (this.min.x <= box.max.x)) && ((this.max.y >= box.min.y) && (this.min.y <= box.max.y))) && ((this.max.z >= box.min.z) && (this.min.z <= box.max.z)))
297  {
298  result = ((((this.min.x <= box.min.x) && (box.max.x <= this.max.x)) && ((this.min.y <= box.min.y) && (box.max.y <= this.max.y))) && ((this.min.z <= box.min.z) && (box.max.z <= this.max.z))) ? ContainmentType.Contains : ContainmentType.Intersects;
299  }
300 
301  return result;
302  }
303 
304  #endregion
305 
306  public static TSBBox CreateFromCenter(TSVector center, TSVector size) {
307  TSVector half = size * FP.Half;
308  return new TSBBox (center - half, center + half);
309  }
310 
317  #region public static JBBox CreateMerged(JBBox original, JBBox additional)
318 
319  public static TSBBox CreateMerged(TSBBox original, TSBBox additional)
320  {
321  TSBBox result;
322  TSBBox.CreateMerged(ref original, ref additional, out result);
323  return result;
324  }
325 
332  public static void CreateMerged(ref TSBBox original, ref TSBBox additional, out TSBBox result)
333  {
334  TSVector vector;
335  TSVector vector2;
336  TSVector.Min(ref original.min, ref additional.min, out vector2);
337  TSVector.Max(ref original.max, ref additional.max, out vector);
338  result.min = vector2;
339  result.max = vector;
340  }
341 
342  #endregion
343 
344  public TSVector center { get { return (min + max) * (FP.Half); } }
345 
346  public TSVector size {
347  get {
348  return (max - min);
349  }
350  }
351 
352  public TSVector extents {
353  get {
354  return size * FP.Half;
355  }
356  }
357 
358  internal FP Perimeter
359  {
360  get
361  {
362  return (2 * FP.One) * ((max.x - min.x) * (max.y - min.y) +
363  (max.x - min.x) * (max.z - min.z) +
364  (max.z - min.z) * (max.y - min.y));
365  }
366  }
367 
368  public override string ToString() {
369  return min + "|" + max;
370  }
371 
372  }
373 }
static void Absolute(ref TSMatrix matrix, out TSMatrix result)
Changes every sign of the matrix entry to &#39;+&#39;
Definition: TSMath.cs:123
TSVector min
The maximum point of the box.
Definition: TSBBox.cs:49
static void TransposedTransform(ref TSVector position, ref TSMatrix matrix, out TSVector result)
Transforms a vector by the transposed of the given Matrix.
Definition: TSVector.cs:399
ContainmentType Contains(ref TSBBox box)
Checks whether another bounding box is inside, outside or intersecting this box.
Definition: TSBBox.cs:293
void GetCorners(TSVector[] corners)
Retrieves the 8 corners of the box.
Definition: TSBBox.cs:225
static TSBBox CreateFromPoints(TSVector[] points)
Expands a bounding box with the volume 0 by all points given.
Definition: TSBBox.cs:259
ContainmentType
Containment type used within the TSBBox structure.
Definition: TSBBox.cs:30
ContainmentType Contains(TSVector point)
Checks wether a point is within a box or not.
Definition: TSBBox.cs:199
A vector structure.
Definition: TSVector.cs:29
Contains common math operations.
Definition: TSMath.cs:25
static readonly TSBBox LargeBox
Returns the largest box possible.
Definition: TSBBox.cs:59
static TSVector Transform(TSVector position, TSMatrix matrix)
Transforms a vector by the given matrix.
Definition: TSVector.cs:369
ContainmentType Contains(TSBBox box)
Checks whether another bounding box is inside, outside or intersecting this box.
Definition: TSBBox.cs:282
static void CreateMerged(ref TSBBox original, ref TSBBox additional, out TSBBox result)
Creates a new box containing the two given ones.
Definition: TSBBox.cs:332
static TSBBox CreateMerged(TSBBox original, TSBBox additional)
Creates a new box containing the two given ones.
Definition: TSBBox.cs:319
ContainmentType Contains(ref TSVector point)
Checks whether a point is inside, outside or intersecting a point.
Definition: TSBBox.cs:210
3x3 Matrix.
Definition: TSMatrix.cs:26
FP x
The X component of the vector.
Definition: TSVector.cs:37
static readonly TSBBox SmallBox
Returns the smalltest box possible.
Definition: TSBBox.cs:64
static TSVector Add(TSVector value1, TSVector value2)
Adds two vectors.
Definition: TSVector.cs:443
TSVector max
The minimum point of the box.
Definition: TSBBox.cs:54
TSBBox(TSVector min, TSVector max)
Constructor
Definition: TSBBox.cs:79
static TSVector Subtract(TSVector value1, TSVector value2)
Subtracts two vectors.
Definition: TSVector.cs:499
static TSVector Min(TSVector value1, TSVector value2)
Gets a vector with the minimum x,y and z values of both vectors.
Definition: TSVector.cs:277
void Set(FP x, FP y, FP z)
Sets all vector component to specific values.
Definition: TSVector.cs:180
static TSVector Max(TSVector value1, TSVector value2)
Gets a vector with the maximum x,y and z values of both vectors.
Definition: TSVector.cs:305
Bounding Box defined through min and max vectors.
Definition: TSBBox.cs:25
static FP Epsilon
A small value often used to decide if numeric results are zero.
Definition: TSMath.cs:41