Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Collision.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under MIT License. See LICENSE.md for details.
3 //
4 // -----------------------------------------------------------------------------
5 // Original code from SlimMath project. http://code.google.com/p/slimmath/
6 // Greetings to SlimDX Group. Original code published with the following license:
7 // -----------------------------------------------------------------------------
8 /*
9 * Copyright (c) 2007-2011 SlimDX Group
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 */
29 using System;
30 
31 namespace SiliconStudio.Core.Mathematics
32 {
33  /*
34  * This class is organized so that the least complex objects come first so that the least
35  * complex objects will have the most methods in most cases. Note that not all shapes exist
36  * at this time and not all shapes have a corresponding struct. Only the objects that have
37  * a corresponding struct should come first in naming and in parameter order. The order of
38  * complexity is as follows:
39  *
40  * 1. Point
41  * 2. Ray
42  * 3. Segment
43  * 4. Plane
44  * 5. Triangle
45  * 6. Polygon
46  * 7. Box
47  * 8. Sphere
48  * 9. Ellipsoid
49  * 10. Cylinder
50  * 11. Cone
51  * 12. Capsule
52  * 13. Torus
53  * 14. Polyhedron
54  * 15. Frustum
55  */
56 
57  /// <summary>
58  /// Contains static methods to help in determining intersections, containment, etc.
59  /// </summary>
60  public static class Collision
61  {
62  /// <summary>
63  /// Determines the closest point between a point and a triangle.
64  /// </summary>
65  /// <param name="point">The point to test.</param>
66  /// <param name="vertex1">The first vertex to test.</param>
67  /// <param name="vertex2">The second vertex to test.</param>
68  /// <param name="vertex3">The third vertex to test.</param>
69  /// <param name="result">When the method completes, contains the closest point between the two objects.</param>
70  public static void ClosestPointPointTriangle(ref Vector3 point, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 result)
71  {
72  //Source: Real-Time Collision Detection by Christer Ericson
73  //Reference: Page 136
74 
75  //Check if P in vertex region outside A
76  Vector3 ab = vertex2 - vertex1;
77  Vector3 ac = vertex3 - vertex1;
78  Vector3 ap = point - vertex1;
79 
80  float d1 = Vector3.Dot(ab, ap);
81  float d2 = Vector3.Dot(ac, ap);
82  if (d1 <= 0.0f && d2 <= 0.0f)
83  result = vertex1; //Barycentric coordinates (1,0,0)
84 
85  //Check if P in vertex region outside B
86  Vector3 bp = point - vertex2;
87  float d3 = Vector3.Dot(ab, bp);
88  float d4 = Vector3.Dot(ac, bp);
89  if (d3 >= 0.0f && d4 <= d3)
90  result = vertex2; // barycentric coordinates (0,1,0)
91 
92  //Check if P in edge region of AB, if so return projection of P onto AB
93  float vc = d1 * d4 - d3 * d2;
94  if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f)
95  {
96  float v = d1 / (d1 - d3);
97  result = vertex1 + v * ab; //Barycentric coordinates (1-v,v,0)
98  }
99 
100  //Check if P in vertex region outside C
101  Vector3 cp = point - vertex3;
102  float d5 = Vector3.Dot(ab, cp);
103  float d6 = Vector3.Dot(ac, cp);
104  if (d6 >= 0.0f && d5 <= d6)
105  result = vertex3; //Barycentric coordinates (0,0,1)
106 
107  //Check if P in edge region of AC, if so return projection of P onto AC
108  float vb = d5 * d2 - d1 * d6;
109  if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f)
110  {
111  float w = d2 / (d2 - d6);
112  result = vertex1 + w * ac; //Barycentric coordinates (1-w,0,w)
113  }
114 
115  //Check if P in edge region of BC, if so return projection of P onto BC
116  float va = d3 * d6 - d5 * d4;
117  if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f)
118  {
119  float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
120  result = vertex2 + w * (vertex3 - vertex2); //Barycentric coordinates (0,1-w,w)
121  }
122 
123  //P inside face region. Compute Q through its barycentric coordinates (u,v,w)
124  float denom = 1.0f / (va + vb + vc);
125  float v2 = vb * denom;
126  float w2 = vc * denom;
127  result = vertex1 + ab * v2 + ac * w2; //= u*vertex1 + v*vertex2 + w*vertex3, u = va * denom = 1.0f - v - w
128  }
129 
130  /// <summary>
131  /// Determines the closest point between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a point.
132  /// </summary>
133  /// <param name="plane">The plane to test.</param>
134  /// <param name="point">The point to test.</param>
135  /// <param name="result">When the method completes, contains the closest point between the two objects.</param>
136  public static void ClosestPointPlanePoint(ref Plane plane, ref Vector3 point, out Vector3 result)
137  {
138  //Source: Real-Time Collision Detection by Christer Ericson
139  //Reference: Page 126
140 
141  float dot;
142  Vector3.Dot(ref plane.Normal, ref point, out dot);
143  float t = dot - plane.D;
144 
145  result = point - (t * plane.Normal);
146  }
147 
148  /// <summary>
149  /// Determines the closest point between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a point.
150  /// </summary>
151  /// <param name="box">The box to test.</param>
152  /// <param name="point">The point to test.</param>
153  /// <param name="result">When the method completes, contains the closest point between the two objects.</param>
154  public static void ClosestPointBoxPoint(ref BoundingBox box, ref Vector3 point, out Vector3 result)
155  {
156  //Source: Real-Time Collision Detection by Christer Ericson
157  //Reference: Page 130
158 
159  Vector3 temp;
160  Vector3.Max(ref point, ref box.Minimum, out temp);
161  Vector3.Min(ref temp, ref box.Maximum, out result);
162  }
163 
164  /// <summary>
165  /// Determines the closest point between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a point.
166  /// </summary>
167  /// <param name="sphere"></param>
168  /// <param name="point">The point to test.</param>
169  /// <param name="result">When the method completes, contains the closest point between the two objects;
170  /// or, if the point is directly in the center of the sphere, contains <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/>.</param>
171  public static void ClosestPointSpherePoint(ref BoundingSphere sphere, ref Vector3 point, out Vector3 result)
172  {
173  //Source: Jorgy343
174  //Reference: None
175 
176  //Get the unit direction from the sphere's center to the point.
177  Vector3.Subtract(ref point, ref sphere.Center, out result);
178  result.Normalize();
179 
180  //Multiply the unit direction by the sphere's radius to get a vector
181  //the length of the sphere.
182  result *= sphere.Radius;
183 
184  //Add the sphere's center to the direction to get a point on the sphere.
185  result += sphere.Center;
186  }
187 
188  /// <summary>
189  /// Determines the closest point between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
190  /// </summary>
191  /// <param name="sphere1">The first sphere to test.</param>
192  /// <param name="sphere2">The second sphere to test.</param>
193  /// <param name="result">When the method completes, contains the closest point between the two objects;
194  /// or, if the point is directly in the center of the sphere, contains <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/>.</param>
195  /// <remarks>
196  /// If the two spheres are overlapping, but not directly ontop of each other, the closest point
197  /// is the 'closest' point of intersection. This can also be considered is the deepest point of
198  /// intersection.
199  /// </remarks>
200  public static void ClosestPointSphereSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2, out Vector3 result)
201  {
202  //Source: Jorgy343
203  //Reference: None
204 
205  //Get the unit direction from the first sphere's center to the second sphere's center.
206  Vector3.Subtract(ref sphere2.Center, ref sphere1.Center, out result);
207  result.Normalize();
208 
209  //Multiply the unit direction by the first sphere's radius to get a vector
210  //the length of the first sphere.
211  result *= sphere1.Radius;
212 
213  //Add the first sphere's center to the direction to get a point on the first sphere.
214  result += sphere1.Center;
215  }
216 
217  /// <summary>
218  /// Determines the distance between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a point.
219  /// </summary>
220  /// <param name="plane">The plane to test.</param>
221  /// <param name="point">The point to test.</param>
222  /// <returns>The distance between the two objects.</returns>
223  public static float DistancePlanePoint(ref Plane plane, ref Vector3 point)
224  {
225  //Source: Real-Time Collision Detection by Christer Ericson
226  //Reference: Page 127
227 
228  float dot;
229  Vector3.Dot(ref plane.Normal, ref point, out dot);
230  return dot - plane.D;
231  }
232 
233  /// <summary>
234  /// Determines the distance between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a point.
235  /// </summary>
236  /// <param name="box">The box to test.</param>
237  /// <param name="point">The point to test.</param>
238  /// <returns>The distance between the two objects.</returns>
239  public static float DistanceBoxPoint(ref BoundingBox box, ref Vector3 point)
240  {
241  //Source: Real-Time Collision Detection by Christer Ericson
242  //Reference: Page 131
243 
244  float distance = 0f;
245 
246  if (point.X < box.Minimum.X)
247  distance += (box.Minimum.X - point.X) * (box.Minimum.X - point.X);
248  if (point.X > box.Maximum.X)
249  distance += (point.X - box.Maximum.X) * (point.X - box.Maximum.X);
250 
251  if (point.Y < box.Minimum.Y)
252  distance += (box.Minimum.Y - point.Y) * (box.Minimum.Y - point.Y);
253  if (point.Y > box.Maximum.Y)
254  distance += (point.Y - box.Maximum.Y) * (point.Y - box.Maximum.Y);
255 
256  if (point.Z < box.Minimum.Z)
257  distance += (box.Minimum.Z - point.Z) * (box.Minimum.Z - point.Z);
258  if (point.Z > box.Maximum.Z)
259  distance += (point.Z - box.Maximum.Z) * (point.Z - box.Maximum.Z);
260 
261  return (float)Math.Sqrt(distance);
262  }
263 
264  /// <summary>
265  /// Determines the distance between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
266  /// </summary>
267  /// <param name="box1">The first box to test.</param>
268  /// <param name="box2">The second box to test.</param>
269  /// <returns>The distance between the two objects.</returns>
270  public static float DistanceBoxBox(ref BoundingBox box1, ref BoundingBox box2)
271  {
272  //Source:
273  //Reference:
274 
275  float distance = 0f;
276 
277  //Distance for X.
278  if (box1.Minimum.X > box2.Maximum.X)
279  {
280  float delta = box2.Maximum.X - box1.Minimum.X;
281  distance += delta * delta;
282  }
283  else if (box2.Minimum.X > box1.Maximum.X)
284  {
285  float delta = box1.Maximum.X - box2.Minimum.X;
286  distance += delta * delta;
287  }
288 
289  //Distance for Y.
290  if (box1.Minimum.Y > box2.Maximum.Y)
291  {
292  float delta = box2.Maximum.Y - box1.Minimum.Y;
293  distance += delta * delta;
294  }
295  else if (box2.Minimum.Y > box1.Maximum.Y)
296  {
297  float delta = box1.Maximum.Y - box2.Minimum.Y;
298  distance += delta * delta;
299  }
300 
301  //Distance for Z.
302  if (box1.Minimum.Z > box2.Maximum.Z)
303  {
304  float delta = box2.Maximum.Z - box1.Minimum.Z;
305  distance += delta * delta;
306  }
307  else if (box2.Minimum.Z > box1.Maximum.Z)
308  {
309  float delta = box1.Maximum.Z - box2.Minimum.Z;
310  distance += delta * delta;
311  }
312 
313  return (float)Math.Sqrt(distance);
314  }
315 
316  /// <summary>
317  /// Determines the distance between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a point.
318  /// </summary>
319  /// <param name="sphere">The sphere to test.</param>
320  /// <param name="point">The point to test.</param>
321  /// <returns>The distance between the two objects.</returns>
322  public static float DistanceSpherePoint(ref BoundingSphere sphere, ref Vector3 point)
323  {
324  //Source: Jorgy343
325  //Reference: None
326 
327  float distance;
328  Vector3.Distance(ref sphere.Center, ref point, out distance);
329  distance -= sphere.Radius;
330 
331  return Math.Max(distance, 0f);
332  }
333 
334  /// <summary>
335  /// Determines the distance between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
336  /// </summary>
337  /// <param name="sphere1">The first sphere to test.</param>
338  /// <param name="sphere2">The second sphere to test.</param>
339  /// <returns>The distance between the two objects.</returns>
340  public static float DistanceSphereSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
341  {
342  //Source: Jorgy343
343  //Reference: None
344 
345  float distance;
346  Vector3.Distance(ref sphere1.Center, ref sphere2.Center, out distance);
347  distance -= sphere1.Radius + sphere2.Radius;
348 
349  return Math.Max(distance, 0f);
350  }
351 
352  /// <summary>
353  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a point.
354  /// </summary>
355  /// <param name="ray">The ray to test.</param>
356  /// <param name="point">The point to test.</param>
357  /// <returns>Whether the two objects intersect.</returns>
358  public static bool RayIntersectsPoint(ref Ray ray, ref Vector3 point)
359  {
360  //Source: RayIntersectsSphere
361  //Reference: None
362 
363  Vector3 m;
364  Vector3.Subtract(ref ray.Position, ref point, out m);
365 
366  //Same thing as RayIntersectsSphere except that the radius of the sphere (point)
367  //is the epsilon for zero.
368  float b = Vector3.Dot(m, ray.Direction);
369  float c = Vector3.Dot(m, m) - MathUtil.ZeroTolerance;
370 
371  if (c > 0f && b > 0f)
372  return false;
373 
374  float discriminant = b * b - c;
375 
376  if (discriminant < 0f)
377  return false;
378 
379  return true;
380  }
381 
382  /// <summary>
383  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.Ray"/>.
384  /// </summary>
385  /// <param name="ray1">The first ray to test.</param>
386  /// <param name="ray2">The second ray to test.</param>
387  /// <param name="point">When the method completes, contains the point of intersection,
388  /// or <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/> if there was no intersection.</param>
389  /// <returns>Whether the two objects intersect.</returns>
390  /// <remarks>
391  /// This method performs a ray vs ray intersection test based on the following formula
392  /// from Goldman.
393  /// <code>s = det([o_2 - o_1, d_2, d_1 x d_2]) / ||d_1 x d_2||^2</code>
394  /// <code>t = det([o_2 - o_1, d_1, d_1 x d_2]) / ||d_1 x d_2||^2</code>
395  /// Where o_1 is the position of the first ray, o_2 is the position of the second ray,
396  /// d_1 is the normalized direction of the first ray, d_2 is the normalized direction
397  /// of the second ray, det denotes the determinant of a matrix, x denotes the cross
398  /// product, [ ] denotes a matrix, and || || denotes the length or magnitude of a vector.
399  /// </remarks>
400  public static bool RayIntersectsRay(ref Ray ray1, ref Ray ray2, out Vector3 point)
401  {
402  //Source: Real-Time Rendering, Third Edition
403  //Reference: Page 780
404 
405  Vector3 cross;
406 
407  Vector3.Cross(ref ray1.Direction, ref ray2.Direction, out cross);
408  float denominator = cross.Length();
409 
410  //Lines are parallel.
411  if (Math.Abs(denominator) < MathUtil.ZeroTolerance)
412  {
413  //Lines are parallel and on top of each other.
414  if (Math.Abs(ray2.Position.X - ray1.Position.X) < MathUtil.ZeroTolerance &&
415  Math.Abs(ray2.Position.Y - ray1.Position.Y) < MathUtil.ZeroTolerance &&
416  Math.Abs(ray2.Position.Z - ray1.Position.Z) < MathUtil.ZeroTolerance)
417  {
418  point = Vector3.Zero;
419  return true;
420  }
421  }
422 
423  denominator = denominator * denominator;
424 
425  //3x3 matrix for the first ray.
426  float m11 = ray2.Position.X - ray1.Position.X;
427  float m12 = ray2.Position.Y - ray1.Position.Y;
428  float m13 = ray2.Position.Z - ray1.Position.Z;
429  float m21 = ray2.Direction.X;
430  float m22 = ray2.Direction.Y;
431  float m23 = ray2.Direction.Z;
432  float m31 = cross.X;
433  float m32 = cross.Y;
434  float m33 = cross.Z;
435 
436  //Determinant of first matrix.
437  float dets =
438  m11 * m22 * m33 +
439  m12 * m23 * m31 +
440  m13 * m21 * m32 -
441  m11 * m23 * m32 -
442  m12 * m21 * m33 -
443  m13 * m22 * m31;
444 
445  //3x3 matrix for the second ray.
446  m21 = ray1.Direction.X;
447  m22 = ray1.Direction.Y;
448  m23 = ray1.Direction.Z;
449 
450  //Determinant of the second matrix.
451  float dett =
452  m11 * m22 * m33 +
453  m12 * m23 * m31 +
454  m13 * m21 * m32 -
455  m11 * m23 * m32 -
456  m12 * m21 * m33 -
457  m13 * m22 * m31;
458 
459  //t values of the point of intersection.
460  float s = dets / denominator;
461  float t = dett / denominator;
462 
463  //The points of intersection.
464  Vector3 point1 = ray1.Position + (s * ray1.Direction);
465  Vector3 point2 = ray2.Position + (t * ray2.Direction);
466 
467  //If the points are not equal, no intersection has occured.
468  if (Math.Abs(point2.X - point1.X) > MathUtil.ZeroTolerance ||
469  Math.Abs(point2.Y - point1.Y) > MathUtil.ZeroTolerance ||
470  Math.Abs(point2.Z - point1.Z) > MathUtil.ZeroTolerance)
471  {
472  point = Vector3.Zero;
473  return false;
474  }
475 
476  point = point1;
477  return true;
478  }
479 
480  /// <summary>
481  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.Plane"/>.
482  /// </summary>
483  /// <param name="ray">The ray to test.</param>
484  /// <param name="plane">The plane to test.</param>
485  /// <param name="distance">When the method completes, contains the distance of the intersection,
486  /// or 0 if there was no intersection.</param>
487  /// <returns>Whether the two objects intersect.</returns>
488  public static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out float distance)
489  {
490  //Source: Real-Time Collision Detection by Christer Ericson
491  //Reference: Page 175
492 
493  float direction;
494  Vector3.Dot(ref plane.Normal, ref ray.Direction, out direction);
495 
496  if (Math.Abs(direction) < MathUtil.ZeroTolerance)
497  {
498  distance = 0f;
499  return false;
500  }
501 
502  float position;
503  Vector3.Dot(ref plane.Normal, ref ray.Position, out position);
504  distance = (-plane.D - position) / direction;
505 
506  if (distance < 0f)
507  {
508  if (distance < -MathUtil.ZeroTolerance)
509  {
510  distance = 0;
511  return false;
512  }
513 
514  distance = 0f;
515  }
516 
517  return true;
518  }
519 
520  /// <summary>
521  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.Plane"/>.
522  /// </summary>
523  /// <param name="ray">The ray to test.</param>
524  /// <param name="plane">The plane to test</param>
525  /// <param name="point">When the method completes, contains the point of intersection,
526  /// or <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/> if there was no intersection.</param>
527  /// <returns>Whether the two objects intersected.</returns>
528  public static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out Vector3 point)
529  {
530  //Source: Real-Time Collision Detection by Christer Ericson
531  //Reference: Page 175
532 
533  float distance;
534  if (!RayIntersectsPlane(ref ray, ref plane, out distance))
535  {
536  point = Vector3.Zero;
537  return false;
538  }
539 
540  point = ray.Position + (ray.Direction * distance);
541  return true;
542  }
543 
544  /// <summary>
545  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a triangle.
546  /// </summary>
547  /// <param name="ray">The ray to test.</param>
548  /// <param name="vertex1">The first vertex of the triangle to test.</param>
549  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
550  /// <param name="vertex3">The third vertex of the triangle to test.</param>
551  /// <param name="distance">When the method completes, contains the distance of the intersection,
552  /// or 0 if there was no intersection.</param>
553  /// <returns>Whether the two objects intersected.</returns>
554  /// <remarks>
555  /// This method tests if the ray intersects either the front or back of the triangle.
556  /// If the ray is parallel to the triangle's plane, no intersection is assumed to have
557  /// happened. If the intersection of the ray and the triangle is behind the origin of
558  /// the ray, no intersection is assumed to have happened. In both cases of assumptions,
559  /// this method returns false.
560  /// </remarks>
561  public static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out float distance)
562  {
563  //Source: Fast Minimum Storage Ray / Triangle Intersection
564  //Reference: http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
565 
566  //Compute vectors along two edges of the triangle.
567  Vector3 edge1, edge2;
568 
569  //Edge 1
570  edge1.X = vertex2.X - vertex1.X;
571  edge1.Y = vertex2.Y - vertex1.Y;
572  edge1.Z = vertex2.Z - vertex1.Z;
573 
574  //Edge2
575  edge2.X = vertex3.X - vertex1.X;
576  edge2.Y = vertex3.Y - vertex1.Y;
577  edge2.Z = vertex3.Z - vertex1.Z;
578 
579  //Cross product of ray direction and edge2 - first part of determinant.
580  Vector3 directioncrossedge2;
581  directioncrossedge2.X = (ray.Direction.Y * edge2.Z) - (ray.Direction.Z * edge2.Y);
582  directioncrossedge2.Y = (ray.Direction.Z * edge2.X) - (ray.Direction.X * edge2.Z);
583  directioncrossedge2.Z = (ray.Direction.X * edge2.Y) - (ray.Direction.Y * edge2.X);
584 
585  //Compute the determinant.
586  float determinant;
587  //Dot product of edge1 and the first part of determinant.
588  determinant = (edge1.X * directioncrossedge2.X) + (edge1.Y * directioncrossedge2.Y) + (edge1.Z * directioncrossedge2.Z);
589 
590  //If the ray is parallel to the triangle plane, there is no collision.
591  //This also means that we are not culling, the ray may hit both the
592  //back and the front of the triangle.
593  if (determinant > -MathUtil.ZeroTolerance && determinant < MathUtil.ZeroTolerance)
594  {
595  distance = 0f;
596  return false;
597  }
598 
599  float inversedeterminant = 1.0f / determinant;
600 
601  //Calculate the U parameter of the intersection point.
602  Vector3 distanceVector;
603  distanceVector.X = ray.Position.X - vertex1.X;
604  distanceVector.Y = ray.Position.Y - vertex1.Y;
605  distanceVector.Z = ray.Position.Z - vertex1.Z;
606 
607  float triangleU;
608  triangleU = (distanceVector.X * directioncrossedge2.X) + (distanceVector.Y * directioncrossedge2.Y) + (distanceVector.Z * directioncrossedge2.Z);
609  triangleU *= inversedeterminant;
610 
611  //Make sure it is inside the triangle.
612  if (triangleU < 0f || triangleU > 1f)
613  {
614  distance = 0f;
615  return false;
616  }
617 
618  //Calculate the V parameter of the intersection point.
619  Vector3 distancecrossedge1;
620  distancecrossedge1.X = (distanceVector.Y * edge1.Z) - (distanceVector.Z * edge1.Y);
621  distancecrossedge1.Y = (distanceVector.Z * edge1.X) - (distanceVector.X * edge1.Z);
622  distancecrossedge1.Z = (distanceVector.X * edge1.Y) - (distanceVector.Y * edge1.X);
623 
624  float triangleV;
625  triangleV = ((ray.Direction.X * distancecrossedge1.X) + (ray.Direction.Y * distancecrossedge1.Y)) + (ray.Direction.Z * distancecrossedge1.Z);
626  triangleV *= inversedeterminant;
627 
628  //Make sure it is inside the triangle.
629  if (triangleV < 0f || triangleU + triangleV > 1f)
630  {
631  distance = 0f;
632  return false;
633  }
634 
635  //Compute the distance along the ray to the triangle.
636  float raydistance;
637  raydistance = (edge2.X * distancecrossedge1.X) + (edge2.Y * distancecrossedge1.Y) + (edge2.Z * distancecrossedge1.Z);
638  raydistance *= inversedeterminant;
639 
640  //Is the triangle behind the ray origin?
641  if (raydistance < 0f)
642  {
643  distance = 0f;
644  return false;
645  }
646 
647  distance = raydistance;
648  return true;
649  }
650 
651  /// <summary>
652  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a triangle.
653  /// </summary>
654  /// <param name="ray">The ray to test.</param>
655  /// <param name="vertex1">The first vertex of the triangle to test.</param>
656  /// <param name="vertex2">The second vertex of the triangle to test.</param>
657  /// <param name="vertex3">The third vertex of the triangle to test.</param>
658  /// <param name="point">When the method completes, contains the point of intersection,
659  /// or <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/> if there was no intersection.</param>
660  /// <returns>Whether the two objects intersected.</returns>
661  public static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 point)
662  {
663  float distance;
664  if (!RayIntersectsTriangle(ref ray, ref vertex1, ref vertex2, ref vertex3, out distance))
665  {
666  point = Vector3.Zero;
667  return false;
668  }
669 
670  point = ray.Position + (ray.Direction * distance);
671  return true;
672  }
673 
674  /// <summary>
675  /// Determines whether there is an intersection between a <see cref="Ray"/> and a rectangle (2D).
676  /// </summary>
677  /// <param name="ray">The ray to test</param>
678  /// <param name="rectangleWorldMatrix">The world matrix applied on the rectangle</param>
679  /// <param name="rectangleSize">The size of the rectangle in 3D</param>
680  /// <param name="normalAxis">The index of axis defining the normal of the rectangle in the world. This value should be 0, 1 or 2</param>
681  /// <param name="intersectionPoint">The position of the intersection point in the world</param>
682  /// <returns><value>true</value> if the ray and rectangle intersects.</returns>
683  public static bool RayIntersectsRectangle(ref Ray ray, ref Matrix rectangleWorldMatrix, ref Vector3 rectangleSize, int normalAxis, out Vector3 intersectionPoint)
684  {
685  bool intersects;
686 
687  int testAxis1;
688  int testAxis2;
689  switch (normalAxis)
690  {
691  case 0:
692  testAxis1 = 1;
693  testAxis2 = 2;
694  break;
695  case 1:
696  testAxis1 = 2;
697  testAxis2 = 0;
698  break;
699  case 2:
700  testAxis1 = 0;
701  testAxis2 = 1;
702  break;
703  default:
704  throw new ArgumentOutOfRangeException("normalAxis");
705  }
706 
707  var rectanglePosition = new Vector3(rectangleWorldMatrix.M41, rectangleWorldMatrix.M42, rectangleWorldMatrix.M43);
708 
709  var normalRowStart = normalAxis << 2;
710  var plane = new Plane(rectanglePosition, new Vector3(rectangleWorldMatrix[normalRowStart], rectangleWorldMatrix[normalRowStart + 1], rectangleWorldMatrix[normalRowStart + 2]));
711 
712  // early exist the planes were parallels
713  if (!plane.Intersects(ref ray, out intersectionPoint))
714  return false;
715 
716  // the position of the intersection point with respect to the rectangle center
717  var intersectionInRectangle = intersectionPoint - rectanglePosition;
718 
719  // optimization for the simple but very frequent case where the element is not rotated
720  if (rectangleWorldMatrix.M12 == 0 && rectangleWorldMatrix.M13 == 0 &&
721  rectangleWorldMatrix.M21 == 0 && rectangleWorldMatrix.M23 == 0 &&
722  rectangleWorldMatrix.M31 == 0 && rectangleWorldMatrix.M32 == 0)
723  {
724  var halfSize1 = rectangleWorldMatrix[(testAxis1 << 2) + testAxis1] * rectangleSize[testAxis1] / 2f;
725  var halfSize2 = rectangleWorldMatrix[(testAxis2 << 2) + testAxis2] * rectangleSize[testAxis2] / 2f;
726 
727  intersects = -halfSize1 <= intersectionInRectangle[testAxis1] && intersectionInRectangle[testAxis1] <= halfSize1 &&
728  -halfSize2 <= intersectionInRectangle[testAxis2] && intersectionInRectangle[testAxis2] <= halfSize2;
729  }
730  else // general case: decompose the rectangle into two triangles and check that all angles are less than 180 degrees in at least one of the triangles.
731  {
732  // find the most significant component of the plane normal
733  var normalTestIndex = 0;
734  for (int i = 1; i < 3; i++)
735  {
736  if (Math.Abs(plane.Normal[i]) > Math.Abs(plane.Normal[normalTestIndex]))
737  normalTestIndex = i;
738  }
739  var normalSign = Math.Sign(plane.Normal[normalTestIndex]);
740 
741  // the base vector
742  var base1 = rectangleSize[testAxis1] * new Vector3(rectangleWorldMatrix[(testAxis1 << 2)], rectangleWorldMatrix[(testAxis1 << 2) + 1], rectangleWorldMatrix[(testAxis1 << 2) + 2]) / 2;
743  var base2 = rectangleSize[testAxis2] * new Vector3(rectangleWorldMatrix[(testAxis2 << 2)], rectangleWorldMatrix[(testAxis2 << 2) + 1], rectangleWorldMatrix[(testAxis2 << 2) + 2]) / 2;
744 
745  // build the first triangle and perform the test
746  var v1 = -base1 - base2 - intersectionInRectangle;
747  var v2 = +base1 - base2 - intersectionInRectangle;
748  var v3 = +base1 + base2 - intersectionInRectangle;
749 
750  intersects = Math.Sign(Vector3.Cross(v1, v2)[normalTestIndex]) == normalSign &&
751  Math.Sign(Vector3.Cross(v2, v3)[normalTestIndex]) == normalSign &&
752  Math.Sign(Vector3.Cross(v3, v1)[normalTestIndex]) == normalSign;
753 
754  // early exit on success
755  if (intersects)
756  return true;
757 
758  // build second triangle and perform the test
759  v1 = -base1 - base2 - intersectionInRectangle;
760  v2 = +base1 + base2 - intersectionInRectangle;
761  v3 = -base1 + base2 - intersectionInRectangle;
762 
763  intersects = Math.Sign(Vector3.Cross(v1, v2)[normalTestIndex]) == normalSign &&
764  Math.Sign(Vector3.Cross(v2, v3)[normalTestIndex]) == normalSign &&
765  Math.Sign(Vector3.Cross(v3, v1)[normalTestIndex]) == normalSign;
766  }
767 
768  return intersects;
769  }
770 
771  /// <summary>
772  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
773  /// </summary>
774  /// <param name="ray">The ray to test.</param>
775  /// <param name="box">The box to test.</param>
776  /// <param name="distance">When the method completes, contains the distance of the intersection,
777  /// or 0 if there was no intersection.</param>
778  /// <returns>Whether the two objects intersected.</returns>
779  public static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out float distance)
780  {
781  //Source: Real-Time Collision Detection by Christer Ericson
782  //Reference: Page 179
783 
784  distance = 0f;
785  float tmax = float.MaxValue;
786 
787  if (Math.Abs(ray.Direction.X) < MathUtil.ZeroTolerance)
788  {
789  if (ray.Position.X < box.Minimum.X || ray.Position.X > box.Maximum.X)
790  {
791  distance = 0f;
792  return false;
793  }
794  }
795  else
796  {
797  float inverse = 1.0f / ray.Direction.X;
798  float t1 = (box.Minimum.X - ray.Position.X) * inverse;
799  float t2 = (box.Maximum.X - ray.Position.X) * inverse;
800 
801  if (t1 > t2)
802  {
803  float temp = t1;
804  t1 = t2;
805  t2 = temp;
806  }
807 
808  distance = Math.Max(t1, distance);
809  tmax = Math.Min(t2, tmax);
810 
811  if (distance > tmax)
812  {
813  distance = 0f;
814  return false;
815  }
816  }
817 
818  if (Math.Abs(ray.Direction.Y) < MathUtil.ZeroTolerance)
819  {
820  if (ray.Position.Y < box.Minimum.Y || ray.Position.Y > box.Maximum.Y)
821  {
822  distance = 0f;
823  return false;
824  }
825  }
826  else
827  {
828  float inverse = 1.0f / ray.Direction.Y;
829  float t1 = (box.Minimum.Y - ray.Position.Y) * inverse;
830  float t2 = (box.Maximum.Y - ray.Position.Y) * inverse;
831 
832  if (t1 > t2)
833  {
834  float temp = t1;
835  t1 = t2;
836  t2 = temp;
837  }
838 
839  distance = Math.Max(t1, distance);
840  tmax = Math.Min(t2, tmax);
841 
842  if (distance > tmax)
843  {
844  distance = 0f;
845  return false;
846  }
847  }
848 
849  if (Math.Abs(ray.Direction.Z) < MathUtil.ZeroTolerance)
850  {
851  if (ray.Position.Z < box.Minimum.Z || ray.Position.Z > box.Maximum.Z)
852  {
853  distance = 0f;
854  return false;
855  }
856  }
857  else
858  {
859  float inverse = 1.0f / ray.Direction.Z;
860  float t1 = (box.Minimum.Z - ray.Position.Z) * inverse;
861  float t2 = (box.Maximum.Z - ray.Position.Z) * inverse;
862 
863  if (t1 > t2)
864  {
865  float temp = t1;
866  t1 = t2;
867  t2 = temp;
868  }
869 
870  distance = Math.Max(t1, distance);
871  tmax = Math.Min(t2, tmax);
872 
873  if (distance > tmax)
874  {
875  distance = 0f;
876  return false;
877  }
878  }
879 
880  return true;
881  }
882 
883  /// <summary>
884  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.Plane"/>.
885  /// </summary>
886  /// <param name="ray">The ray to test.</param>
887  /// <param name="box">The box to test.</param>
888  /// <param name="point">When the method completes, contains the point of intersection,
889  /// or <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/> if there was no intersection.</param>
890  /// <returns>Whether the two objects intersected.</returns>
891  public static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out Vector3 point)
892  {
893  float distance;
894  if (!RayIntersectsBox(ref ray, ref box, out distance))
895  {
896  point = Vector3.Zero;
897  return false;
898  }
899 
900  point = ray.Position + (ray.Direction * distance);
901  return true;
902  }
903 
904  /// <summary>
905  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
906  /// </summary>
907  /// <param name="ray">The ray to test.</param>
908  /// <param name="sphere">The sphere to test.</param>
909  /// <param name="distance">When the method completes, contains the distance of the intersection,
910  /// or 0 if there was no intersection.</param>
911  /// <returns>Whether the two objects intersected.</returns>
912  public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out float distance)
913  {
914  //Source: Real-Time Collision Detection by Christer Ericson
915  //Reference: Page 177
916 
917  Vector3 m;
918  Vector3.Subtract(ref ray.Position, ref sphere.Center, out m);
919 
920  float b = Vector3.Dot(m, ray.Direction);
921  float c = Vector3.Dot(m, m) - (sphere.Radius * sphere.Radius);
922 
923  if (c > 0f && b > 0f)
924  {
925  distance = 0f;
926  return false;
927  }
928 
929  float discriminant = b * b - c;
930 
931  if (discriminant < 0f)
932  {
933  distance = 0f;
934  return false;
935  }
936 
937  distance = -b - (float)Math.Sqrt(discriminant);
938 
939  if (distance < 0f)
940  distance = 0f;
941 
942  return true;
943  }
944 
945  /// <summary>
946  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Ray"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
947  /// </summary>
948  /// <param name="ray">The ray to test.</param>
949  /// <param name="sphere">The sphere to test.</param>
950  /// <param name="point">When the method completes, contains the point of intersection,
951  /// or <see cref="SiliconStudio.Core.Mathematics.Vector3.Zero"/> if there was no intersection.</param>
952  /// <returns>Whether the two objects intersected.</returns>
953  public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out Vector3 point)
954  {
955  float distance;
956  if (!RayIntersectsSphere(ref ray, ref sphere, out distance))
957  {
958  point = Vector3.Zero;
959  return false;
960  }
961 
962  point = ray.Position + (ray.Direction * distance);
963  return true;
964  }
965 
966  /// <summary>
967  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a point.
968  /// </summary>
969  /// <param name="plane">The plane to test.</param>
970  /// <param name="point">The point to test.</param>
971  /// <returns>Whether the two objects intersected.</returns>
972  public static PlaneIntersectionType PlaneIntersectsPoint(ref Plane plane, ref Vector3 point)
973  {
974  float distance;
975  Vector3.Dot(ref plane.Normal, ref point, out distance);
976  distance += plane.D;
977 
978  if (distance > 0f)
979  return PlaneIntersectionType.Front;
980 
981  if (distance < 0f)
982  return PlaneIntersectionType.Back;
983 
984  return PlaneIntersectionType.Intersecting;
985  }
986 
987  /// <summary>
988  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a <see cref="SiliconStudio.Core.Mathematics.Plane"/>.
989  /// </summary>
990  /// <param name="plane1">The first plane to test.</param>
991  /// <param name="plane2">The second plane to test.</param>
992  /// <returns>Whether the two objects intersected.</returns>
993  public static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2)
994  {
995  Vector3 direction;
996  Vector3.Cross(ref plane1.Normal, ref plane2.Normal, out direction);
997 
998  //If direction is the zero vector, the planes are parallel and possibly
999  //coincident. It is not an intersection. The dot product will tell us.
1000  float denominator;
1001  Vector3.Dot(ref direction, ref direction, out denominator);
1002 
1003  if (Math.Abs(denominator) < MathUtil.ZeroTolerance)
1004  return false;
1005 
1006  return true;
1007  }
1008 
1009  /// <summary>
1010  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a <see cref="SiliconStudio.Core.Mathematics.Plane"/>.
1011  /// </summary>
1012  /// <param name="plane1">The first plane to test.</param>
1013  /// <param name="plane2">The second plane to test.</param>
1014  /// <param name="line">When the method completes, contains the line of intersection
1015  /// as a <see cref="SiliconStudio.Core.Mathematics.Ray"/>, or a zero ray if there was no intersection.</param>
1016  /// <returns>Whether the two objects intersected.</returns>
1017  /// <remarks>
1018  /// Although a ray is set to have an origin, the ray returned by this method is really
1019  /// a line in three dimensions which has no real origin. The ray is considered valid when
1020  /// both the positive direction is used and when the negative direction is used.
1021  /// </remarks>
1022  public static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2, out Ray line)
1023  {
1024  //Source: Real-Time Collision Detection by Christer Ericson
1025  //Reference: Page 207
1026 
1027  Vector3 direction;
1028  Vector3.Cross(ref plane1.Normal, ref plane2.Normal, out direction);
1029 
1030  //If direction is the zero vector, the planes are parallel and possibly
1031  //coincident. It is not an intersection. The dot product will tell us.
1032  float denominator;
1033  Vector3.Dot(ref direction, ref direction, out denominator);
1034 
1035  //We assume the planes are normalized, therefore the denominator
1036  //only serves as a parallel and coincident check. Otherwise we need
1037  //to deivide the point by the denominator.
1038  if (Math.Abs(denominator) < MathUtil.ZeroTolerance)
1039  {
1040  line = new Ray();
1041  return false;
1042  }
1043 
1044  Vector3 point;
1045  Vector3 temp = plane1.D * plane2.Normal - plane2.D * plane1.Normal;
1046  Vector3.Cross(ref temp, ref direction, out point);
1047 
1048  line.Position = point;
1049  line.Direction = direction;
1050  line.Direction.Normalize();
1051 
1052  return true;
1053  }
1054 
1055  /// <summary>
1056  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a triangle.
1057  /// </summary>
1058  /// <param name="plane">The plane to test.</param>
1059  /// <param name="vertex1">The first vertex of the triangle to test.</param>
1060  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
1061  /// <param name="vertex3">The third vertex of the triangle to test.</param>
1062  /// <returns>Whether the two objects intersected.</returns>
1063  public static PlaneIntersectionType PlaneIntersectsTriangle(ref Plane plane, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
1064  {
1065  //Source: Real-Time Collision Detection by Christer Ericson
1066  //Reference: Page 207
1067 
1068  PlaneIntersectionType test1 = PlaneIntersectsPoint(ref plane, ref vertex1);
1069  PlaneIntersectionType test2 = PlaneIntersectsPoint(ref plane, ref vertex2);
1070  PlaneIntersectionType test3 = PlaneIntersectsPoint(ref plane, ref vertex3);
1071 
1072  if (test1 == PlaneIntersectionType.Front && test2 == PlaneIntersectionType.Front && test3 == PlaneIntersectionType.Front)
1073  return PlaneIntersectionType.Front;
1074 
1075  if (test1 == PlaneIntersectionType.Back && test2 == PlaneIntersectionType.Back && test3 == PlaneIntersectionType.Back)
1076  return PlaneIntersectionType.Back;
1077 
1078  return PlaneIntersectionType.Intersecting;
1079  }
1080 
1081  /// <summary>
1082  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
1083  /// </summary>
1084  /// <param name="plane">The plane to test.</param>
1085  /// <param name="box">The box to test.</param>
1086  /// <returns>Whether the two objects intersected.</returns>
1087  public static PlaneIntersectionType PlaneIntersectsBox(ref Plane plane, ref BoundingBox box)
1088  {
1089  //Source: Real-Time Collision Detection by Christer Ericson
1090  //Reference: Page 161
1091 
1092  Vector3 min;
1093  Vector3 max;
1094 
1095  max.X = (plane.Normal.X >= 0.0f) ? box.Minimum.X : box.Maximum.X;
1096  max.Y = (plane.Normal.Y >= 0.0f) ? box.Minimum.Y : box.Maximum.Y;
1097  max.Z = (plane.Normal.Z >= 0.0f) ? box.Minimum.Z : box.Maximum.Z;
1098  min.X = (plane.Normal.X >= 0.0f) ? box.Maximum.X : box.Minimum.X;
1099  min.Y = (plane.Normal.Y >= 0.0f) ? box.Maximum.Y : box.Minimum.Y;
1100  min.Z = (plane.Normal.Z >= 0.0f) ? box.Maximum.Z : box.Minimum.Z;
1101 
1102  float distance;
1103  Vector3.Dot(ref plane.Normal, ref max, out distance);
1104 
1105  if (distance + plane.D > 0.0f)
1106  return PlaneIntersectionType.Front;
1107 
1108  distance = Vector3.Dot(plane.Normal, min);
1109 
1110  if (distance + plane.D < 0.0f)
1111  return PlaneIntersectionType.Back;
1112 
1113  return PlaneIntersectionType.Intersecting;
1114  }
1115 
1116  /// <summary>
1117  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.Plane"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
1118  /// </summary>
1119  /// <param name="plane">The plane to test.</param>
1120  /// <param name="sphere">The sphere to test.</param>
1121  /// <returns>Whether the two objects intersected.</returns>
1123  {
1124  //Source: Real-Time Collision Detection by Christer Ericson
1125  //Reference: Page 160
1126 
1127  float distance;
1128  Vector3.Dot(ref plane.Normal, ref sphere.Center, out distance);
1129  distance += plane.D;
1130 
1131  if (distance > sphere.Radius)
1132  return PlaneIntersectionType.Front;
1133 
1134  if (distance < -sphere.Radius)
1135  return PlaneIntersectionType.Back;
1136 
1137  return PlaneIntersectionType.Intersecting;
1138  }
1139 
1140  /* This implentation is wrong
1141  /// <summary>
1142  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a triangle.
1143  /// </summary>
1144  /// <param name="box">The box to test.</param>
1145  /// <param name="vertex1">The first vertex of the triangle to test.</param>
1146  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
1147  /// <param name="vertex3">The third vertex of the triangle to test.</param>
1148  /// <returns>Whether the two objects intersected.</returns>
1149  public static bool BoxIntersectsTriangle(ref BoundingBox box, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
1150  {
1151  if (BoxContainsPoint(ref box, ref vertex1) == ContainmentType.Contains)
1152  return true;
1153 
1154  if (BoxContainsPoint(ref box, ref vertex2) == ContainmentType.Contains)
1155  return true;
1156 
1157  if (BoxContainsPoint(ref box, ref vertex3) == ContainmentType.Contains)
1158  return true;
1159 
1160  return false;
1161  }
1162  */
1163 
1164  /// <summary>
1165  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
1166  /// </summary>
1167  /// <param name="box1">The first box to test.</param>
1168  /// <param name="box2">The second box to test.</param>
1169  /// <returns>Whether the two objects intersected.</returns>
1170  public static bool BoxIntersectsBox(ref BoundingBox box1, ref BoundingBox box2)
1171  {
1172  if (box1.Minimum.X > box2.Maximum.X || box2.Minimum.X > box1.Maximum.X)
1173  return false;
1174 
1175  if (box1.Minimum.Y > box2.Maximum.Y || box2.Minimum.Y > box1.Maximum.Y)
1176  return false;
1177 
1178  if (box1.Minimum.Z > box2.Maximum.Z || box2.Minimum.Z > box1.Maximum.Z)
1179  return false;
1180 
1181  return true;
1182  }
1183 
1184  /// <summary>
1185  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
1186  /// </summary>
1187  /// <param name="box">The box to test.</param>
1188  /// <param name="sphere">The sphere to test.</param>
1189  /// <returns>Whether the two objects intersected.</returns>
1190  public static bool BoxIntersectsSphere(ref BoundingBox box, ref BoundingSphere sphere)
1191  {
1192  //Source: Real-Time Collision Detection by Christer Ericson
1193  //Reference: Page 166
1194 
1195  Vector3 vector;
1196  Vector3.Clamp(ref sphere.Center, ref box.Minimum, ref box.Maximum, out vector);
1197  float distance = Vector3.DistanceSquared(sphere.Center, vector);
1198 
1199  return distance <= sphere.Radius * sphere.Radius;
1200  }
1201 
1202  /// <summary>
1203  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a triangle.
1204  /// </summary>
1205  /// <param name="sphere">The sphere to test.</param>
1206  /// <param name="vertex1">The first vertex of the triangle to test.</param>
1207  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
1208  /// <param name="vertex3">The third vertex of the triangle to test.</param>
1209  /// <returns>Whether the two objects intersected.</returns>
1210  public static bool SphereIntersectsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
1211  {
1212  //Source: Real-Time Collision Detection by Christer Ericson
1213  //Reference: Page 167
1214 
1215  Vector3 point;
1216  ClosestPointPointTriangle(ref sphere.Center, ref vertex1, ref vertex2, ref vertex3, out point);
1217  Vector3 v = point - sphere.Center;
1218 
1219  float dot;
1220  Vector3.Dot(ref v, ref v, out dot);
1221 
1222  return dot <= sphere.Radius * sphere.Radius;
1223  }
1224 
1225  /// <summary>
1226  /// Determines whether there is an intersection between a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> and a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
1227  /// </summary>
1228  /// <param name="sphere1">First sphere to test.</param>
1229  /// <param name="sphere2">Second sphere to test.</param>
1230  /// <returns>Whether the two objects intersected.</returns>
1231  public static bool SphereIntersectsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
1232  {
1233  float radiisum = sphere1.Radius + sphere2.Radius;
1234  return Vector3.DistanceSquared(sphere1.Center, sphere2.Center) <= radiisum * radiisum;
1235  }
1236 
1237  /// <summary>
1238  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> contains a point.
1239  /// </summary>
1240  /// <param name="box">The box to test.</param>
1241  /// <param name="point">The point to test.</param>
1242  /// <returns>The type of containment the two objects have.</returns>
1243  public static ContainmentType BoxContainsPoint(ref BoundingBox box, ref Vector3 point)
1244  {
1245  if (box.Minimum.X <= point.X && box.Maximum.X >= point.X &&
1246  box.Minimum.Y <= point.Y && box.Maximum.Y >= point.Y &&
1247  box.Minimum.Z <= point.Z && box.Maximum.Z >= point.Z)
1248  {
1249  return ContainmentType.Contains;
1250  }
1251 
1252  return ContainmentType.Disjoint;
1253  }
1254 
1255  /* This implentation is wrong
1256  /// <summary>
1257  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> contains a triangle.
1258  /// </summary>
1259  /// <param name="box">The box to test.</param>
1260  /// <param name="vertex1">The first vertex of the triangle to test.</param>
1261  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
1262  /// <param name="vertex3">The third vertex of the triangle to test.</param>
1263  /// <returns>The type of containment the two objects have.</returns>
1264  public static ContainmentType BoxContainsTriangle(ref BoundingBox box, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
1265  {
1266  ContainmentType test1 = BoxContainsPoint(ref box, ref vertex1);
1267  ContainmentType test2 = BoxContainsPoint(ref box, ref vertex2);
1268  ContainmentType test3 = BoxContainsPoint(ref box, ref vertex3);
1269 
1270  if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains)
1271  return ContainmentType.Contains;
1272 
1273  if (test1 == ContainmentType.Contains || test2 == ContainmentType.Contains || test3 == ContainmentType.Contains)
1274  return ContainmentType.Intersects;
1275 
1276  return ContainmentType.Disjoint;
1277  }
1278  */
1279 
1280  /// <summary>
1281  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> contains a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
1282  /// </summary>
1283  /// <param name="box1">The first box to test.</param>
1284  /// <param name="box2">The second box to test.</param>
1285  /// <returns>The type of containment the two objects have.</returns>
1286  public static ContainmentType BoxContainsBox(ref BoundingBox box1, ref BoundingBox box2)
1287  {
1288  if (box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X)
1289  return ContainmentType.Disjoint;
1290 
1291  if (box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y)
1292  return ContainmentType.Disjoint;
1293 
1294  if (box1.Maximum.Z < box2.Minimum.Z || box1.Minimum.Z > box2.Maximum.Z)
1295  return ContainmentType.Disjoint;
1296 
1297  if (box1.Minimum.X <= box2.Minimum.X && (box2.Maximum.X <= box1.Maximum.X &&
1298  box1.Minimum.Y <= box2.Minimum.Y && box2.Maximum.Y <= box1.Maximum.Y) &&
1299  box1.Minimum.Z <= box2.Minimum.Z && box2.Maximum.Z <= box1.Maximum.Z)
1300  {
1301  return ContainmentType.Contains;
1302  }
1303 
1304  return ContainmentType.Intersects;
1305  }
1306 
1307  /// <summary>
1308  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/> contains a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
1309  /// </summary>
1310  /// <param name="box">The box to test.</param>
1311  /// <param name="sphere">The sphere to test.</param>
1312  /// <returns>The type of containment the two objects have.</returns>
1314  {
1315  Vector3 vector;
1316  Vector3.Clamp(ref sphere.Center, ref box.Minimum, ref box.Maximum, out vector);
1317  float distance = Vector3.DistanceSquared(sphere.Center, vector);
1318 
1319  if (distance > sphere.Radius * sphere.Radius)
1320  return ContainmentType.Disjoint;
1321 
1322  if ((((box.Minimum.X + sphere.Radius <= sphere.Center.X) && (sphere.Center.X <= box.Maximum.X - sphere.Radius)) && ((box.Maximum.X - box.Minimum.X > sphere.Radius) &&
1323  (box.Minimum.Y + sphere.Radius <= sphere.Center.Y))) && (((sphere.Center.Y <= box.Maximum.Y - sphere.Radius) && (box.Maximum.Y - box.Minimum.Y > sphere.Radius)) &&
1324  (((box.Minimum.Z + sphere.Radius <= sphere.Center.Z) && (sphere.Center.Z <= box.Maximum.Z - sphere.Radius)) && (box.Maximum.X - box.Minimum.X > sphere.Radius))))
1325  {
1326  return ContainmentType.Contains;
1327  }
1328 
1329  return ContainmentType.Intersects;
1330  }
1331 
1332  /// <summary>
1333  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> contains a point.
1334  /// </summary>
1335  /// <param name="sphere">The sphere to test.</param>
1336  /// <param name="point">The point to test.</param>
1337  /// <returns>The type of containment the two objects have.</returns>
1338  public static ContainmentType SphereContainsPoint(ref BoundingSphere sphere, ref Vector3 point)
1339  {
1340  if (Vector3.DistanceSquared(point, sphere.Center) <= sphere.Radius * sphere.Radius)
1341  return ContainmentType.Contains;
1342 
1343  return ContainmentType.Disjoint;
1344  }
1345 
1346  /// <summary>
1347  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> contains a triangle.
1348  /// </summary>
1349  /// <param name="sphere">The sphere to test.</param>
1350  /// <param name="vertex1">The first vertex of the triangle to test.</param>
1351  /// <param name="vertex2">The second vertex of the triagnle to test.</param>
1352  /// <param name="vertex3">The third vertex of the triangle to test.</param>
1353  /// <returns>The type of containment the two objects have.</returns>
1354  public static ContainmentType SphereContainsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
1355  {
1356  //Source: Jorgy343
1357  //Reference: None
1358 
1359  ContainmentType test1 = SphereContainsPoint(ref sphere, ref vertex1);
1360  ContainmentType test2 = SphereContainsPoint(ref sphere, ref vertex2);
1361  ContainmentType test3 = SphereContainsPoint(ref sphere, ref vertex3);
1362 
1363  if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains)
1364  return ContainmentType.Contains;
1365 
1366  if (SphereIntersectsTriangle(ref sphere, ref vertex1, ref vertex2, ref vertex3))
1367  return ContainmentType.Intersects;
1368 
1369  return ContainmentType.Disjoint;
1370  }
1371 
1372  /// <summary>
1373  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> contains a <see cref="SiliconStudio.Core.Mathematics.BoundingBox"/>.
1374  /// </summary>
1375  /// <param name="sphere">The sphere to test.</param>
1376  /// <param name="box">The box to test.</param>
1377  /// <returns>The type of containment the two objects have.</returns>
1379  {
1380  Vector3 vector;
1381 
1382  if (!BoxIntersectsSphere(ref box, ref sphere))
1383  return ContainmentType.Disjoint;
1384 
1385  float radiussquared = sphere.Radius * sphere.Radius;
1386  vector.X = sphere.Center.X - box.Minimum.X;
1387  vector.Y = sphere.Center.Y - box.Maximum.Y;
1388  vector.Z = sphere.Center.Z - box.Maximum.Z;
1389 
1390  if (vector.LengthSquared() > radiussquared)
1391  return ContainmentType.Intersects;
1392 
1393  vector.X = sphere.Center.X - box.Maximum.X;
1394  vector.Y = sphere.Center.Y - box.Maximum.Y;
1395  vector.Z = sphere.Center.Z - box.Maximum.Z;
1396 
1397  if (vector.LengthSquared() > radiussquared)
1398  return ContainmentType.Intersects;
1399 
1400  vector.X = sphere.Center.X - box.Maximum.X;
1401  vector.Y = sphere.Center.Y - box.Minimum.Y;
1402  vector.Z = sphere.Center.Z - box.Maximum.Z;
1403 
1404  if (vector.LengthSquared() > radiussquared)
1405  return ContainmentType.Intersects;
1406 
1407  vector.X = sphere.Center.X - box.Minimum.X;
1408  vector.Y = sphere.Center.Y - box.Minimum.Y;
1409  vector.Z = sphere.Center.Z - box.Maximum.Z;
1410 
1411  if (vector.LengthSquared() > radiussquared)
1412  return ContainmentType.Intersects;
1413 
1414  vector.X = sphere.Center.X - box.Minimum.X;
1415  vector.Y = sphere.Center.Y - box.Maximum.Y;
1416  vector.Z = sphere.Center.Z - box.Minimum.Z;
1417 
1418  if (vector.LengthSquared() > radiussquared)
1419  return ContainmentType.Intersects;
1420 
1421  vector.X = sphere.Center.X - box.Maximum.X;
1422  vector.Y = sphere.Center.Y - box.Maximum.Y;
1423  vector.Z = sphere.Center.Z - box.Minimum.Z;
1424 
1425  if (vector.LengthSquared() > radiussquared)
1426  return ContainmentType.Intersects;
1427 
1428  vector.X = sphere.Center.X - box.Maximum.X;
1429  vector.Y = sphere.Center.Y - box.Minimum.Y;
1430  vector.Z = sphere.Center.Z - box.Minimum.Z;
1431 
1432  if (vector.LengthSquared() > radiussquared)
1433  return ContainmentType.Intersects;
1434 
1435  vector.X = sphere.Center.X - box.Minimum.X;
1436  vector.Y = sphere.Center.Y - box.Minimum.Y;
1437  vector.Z = sphere.Center.Z - box.Minimum.Z;
1438 
1439  if (vector.LengthSquared() > radiussquared)
1440  return ContainmentType.Intersects;
1441 
1442  return ContainmentType.Contains;
1443  }
1444 
1445  /// <summary>
1446  /// Determines whether a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/> contains a <see cref="SiliconStudio.Core.Mathematics.BoundingSphere"/>.
1447  /// </summary>
1448  /// <param name="sphere1">The first sphere to test.</param>
1449  /// <param name="sphere2">The second sphere to test.</param>
1450  /// <returns>The type of containment the two objects have.</returns>
1451  public static ContainmentType SphereContainsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
1452  {
1453  float distance = Vector3.Distance(sphere1.Center, sphere2.Center);
1454 
1455  if (sphere1.Radius + sphere2.Radius < distance)
1456  return ContainmentType.Disjoint;
1457 
1458  if (sphere1.Radius - sphere2.Radius < distance)
1459  return ContainmentType.Intersects;
1460 
1461  return ContainmentType.Contains;
1462  }
1463 
1464  /// <summary>
1465  /// Determines whether a <see cref="BoundingFrustum"/> intersects or contains an AABB determined by its center and extent.
1466  /// Faster variant specific for frustum culling.
1467  /// </summary>
1468  /// <param name="frustum">The frustum.</param>
1469  /// <param name="center">The center.</param>
1470  /// <param name="extent">The extent.</param>
1471  /// <returns></returns>
1472  public static bool FrustumContainsBox(ref BoundingFrustum frustum, ref Vector3 center, ref Vector3 extent)
1473  {
1474  unsafe
1475  {
1476  fixed (Plane* planeStart = &frustum.Plane1)
1477  {
1478  var plane = planeStart;
1479  for (int i = 0; i < 6; ++i)
1480  {
1481  if (Vector3.Dot(center, plane->Normal)
1482  + extent.X * Math.Abs(plane->Normal.X)
1483  + extent.Y * Math.Abs(plane->Normal.Y)
1484  + extent.Z * Math.Abs(plane->Normal.Z)
1485  <= -plane->D)
1486  return false;
1487 
1488  plane++;
1489  }
1490  }
1491 
1492  return true;
1493  }
1494  }
1495  }
1496 }
static ContainmentType BoxContainsSphere(ref BoundingBox box, ref BoundingSphere sphere)
Determines whether a SiliconStudio.Core.Mathematics.BoundingBox contains a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:1313
static float DistanceSpherePoint(ref BoundingSphere sphere, ref Vector3 point)
Determines the distance between a SiliconStudio.Core.Mathematics.BoundingSphere and a point...
Definition: Collision.cs:322
Represents an axis-aligned bounding box in three dimensional space.
Definition: BoundingBox.cs:42
static PlaneIntersectionType PlaneIntersectsBox(ref Plane plane, ref BoundingBox box)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a SiliconStudio.Core.Mathematics.BoundingBox.
Definition: Collision.cs:1087
static ContainmentType SphereContainsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
Determines whether a SiliconStudio.Core.Mathematics.BoundingSphere contains a triangle.
Definition: Collision.cs:1354
float Y
The Y component of the vector.
Definition: Vector3.cs:84
static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out float distance)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a triangle.
Definition: Collision.cs:561
static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a SiliconStudio.Core.Mathematics.Plane.
Definition: Collision.cs:993
function b
static void Dot(ref Vector3 left, ref Vector3 right, out float result)
Calculates the dot product of two vectors.
Definition: Vector3.cs:585
static bool RayIntersectsRay(ref Ray ray1, ref Ray ray2, out Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.Ray.
Definition: Collision.cs:400
static bool RayIntersectsPoint(ref Ray ray, ref Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a point.
Definition: Collision.cs:358
static ContainmentType SphereContainsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
Determines whether a SiliconStudio.Core.Mathematics.BoundingSphere contains a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:1451
static void ClosestPointPlanePoint(ref Plane plane, ref Vector3 point, out Vector3 result)
Determines the closest point between a SiliconStudio.Core.Mathematics.Plane and a point...
Definition: Collision.cs:136
static ContainmentType BoxContainsPoint(ref BoundingBox box, ref Vector3 point)
Determines whether a SiliconStudio.Core.Mathematics.BoundingBox contains a point. ...
Definition: Collision.cs:1243
float X
The X component of the vector.
Definition: Vector3.cs:78
static void ClosestPointSpherePoint(ref BoundingSphere sphere, ref Vector3 point, out Vector3 result)
Determines the closest point between a SiliconStudio.Core.Mathematics.BoundingSphere and a point...
Definition: Collision.cs:171
const float ZeroTolerance
The value for which all absolute numbers smaller than are considered equal to zero.
Definition: MathUtil.cs:38
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
static bool RayIntersectsRectangle(ref Ray ray, ref Matrix rectangleWorldMatrix, ref Vector3 rectangleSize, int normalAxis, out Vector3 intersectionPoint)
Determines whether there is an intersection between a Ray and a rectangle (2D).
Definition: Collision.cs:683
static bool BoxIntersectsSphere(ref BoundingBox box, ref BoundingSphere sphere)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.BoundingBox and a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:1190
static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.Plane.
Definition: Collision.cs:528
static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out float distance)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:912
Represents a bounding sphere in three dimensional space.
static bool FrustumContainsBox(ref BoundingFrustum frustum, ref Vector3 center, ref Vector3 extent)
Determines whether a BoundingFrustum intersects or contains an AABB determined by its center and exte...
Definition: Collision.cs:1472
static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out float distance)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.Plane.
Definition: Collision.cs:488
Represents a plane in three dimensional space.
Definition: Plane.cs:42
Contains static methods to help in determining intersections, containment, etc.
Definition: Collision.cs:60
ContainmentType
Describes how one bounding volume contains another.
static ContainmentType SphereContainsPoint(ref BoundingSphere sphere, ref Vector3 point)
Determines whether a SiliconStudio.Core.Mathematics.BoundingSphere contains a point.
Definition: Collision.cs:1338
static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a triangle.
Definition: Collision.cs:661
static bool SphereIntersectsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.BoundingSphere and a triangle.
Definition: Collision.cs:1210
static PlaneIntersectionType PlaneIntersectsTriangle(ref Plane plane, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a triangle.
Definition: Collision.cs:1063
static float DistanceSphereSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
Determines the distance between a SiliconStudio.Core.Mathematics.BoundingSphere and a SiliconStudio...
Definition: Collision.cs:340
static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out float distance)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.BoundingBox.
Definition: Collision.cs:779
static void ClosestPointBoxPoint(ref BoundingBox box, ref Vector3 point, out Vector3 result)
Determines the closest point between a SiliconStudio.Core.Mathematics.BoundingBox and a point...
Definition: Collision.cs:154
function s(a)
Represents a three dimensional line based on a point in space and a direction.
Definition: Ray.cs:42
static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.Plane.
Definition: Collision.cs:891
static float DistancePlanePoint(ref Plane plane, ref Vector3 point)
Determines the distance between a SiliconStudio.Core.Mathematics.Plane and a point.
Definition: Collision.cs:223
static void ClosestPointSphereSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2, out Vector3 result)
Determines the closest point between a SiliconStudio.Core.Mathematics.BoundingSphere and a SiliconStu...
Definition: Collision.cs:200
PlaneIntersectionType
Describes the result of an intersection with a plane in three dimensions.
float LengthSquared()
Calculates the squared length of the vector.
Definition: Vector3.cs:208
static bool BoxIntersectsBox(ref BoundingBox box1, ref BoundingBox box2)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.BoundingBox and a SiliconStudio.Core.Mathematics.BoundingBox.
Definition: Collision.cs:1170
static void DistanceSquared(ref Vector3 value1, ref Vector3 value2, out float result)
Calculates the squared distance between two vectors.
Definition: Vector3.cs:548
static PlaneIntersectionType PlaneIntersectsPoint(ref Plane plane, ref Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a point.
Definition: Collision.cs:972
static void ClosestPointPointTriangle(ref Vector3 point, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 result)
Determines the closest point between a point and a triangle.
Definition: Collision.cs:70
static ContainmentType SphereContainsBox(ref BoundingSphere sphere, ref BoundingBox box)
Determines whether a SiliconStudio.Core.Mathematics.BoundingSphere contains a SiliconStudio.Core.Mathematics.BoundingBox.
Definition: Collision.cs:1378
static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out Vector3 point)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Ray and a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:953
SiliconStudio.Core.Mathematics.Vector3 Vector3
static float DistanceBoxPoint(ref BoundingBox box, ref Vector3 point)
Determines the distance between a SiliconStudio.Core.Mathematics.BoundingBox and a point...
Definition: Collision.cs:239
static PlaneIntersectionType PlaneIntersectsSphere(ref Plane plane, ref BoundingSphere sphere)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:1122
static float DistanceBoxBox(ref BoundingBox box1, ref BoundingBox box2)
Determines the distance between a SiliconStudio.Core.Mathematics.BoundingBox and a SiliconStudio...
Definition: Collision.cs:270
float Z
The Z component of the vector.
Definition: Vector3.cs:90
static ContainmentType BoxContainsBox(ref BoundingBox box1, ref BoundingBox box2)
Determines whether a SiliconStudio.Core.Mathematics.BoundingBox contains a SiliconStudio.Core.Mathematics.BoundingBox.
Definition: Collision.cs:1286
static bool SphereIntersectsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.BoundingSphere and a SiliconStudio.Core.Mathematics.BoundingSphere.
Definition: Collision.cs:1231
static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2, out Ray line)
Determines whether there is an intersection between a SiliconStudio.Core.Mathematics.Plane and a SiliconStudio.Core.Mathematics.Plane.
Definition: Collision.cs:1022
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47