ray3.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <ionCore.h>
5 
6 
7 namespace ion
8 {
9 
12  template <typename T>
13  class ray3
14  {
15 
16  public:
17 
20 
21  ray3()
22  {
23  this->Origin = vec3<T>(0);
24  this->Direction = vec3<T>(0, 0, 1);
25  }
26 
27  ray3(vec3<T> const & Origin, vec3<T> const & Direction)
28  {
29  this->Origin = Origin;
30  this->Direction = Direction;
31  }
32 
33  vec3<T> GetPoint(T const Parameter) const
34  {
35  return Origin + Parameter * Direction;
36  }
37 
38  void Transform(glm::mat4 const & Matrix)
39  {
40  Origin.Transform(Matrix, 1);
41  Direction.Transform(Matrix, 0);
42  }
43 
44  ray3 GetTransformed(glm::mat4 const & Matrix) const
45  {
46  ray3 ret;
47  ret.Origin = Origin.GetTransformed(Matrix, 1);
48  ret.Direction = Direction.GetTransformed(Matrix, 0);
49  return ret;
50  }
51 
52 #pragma warning(disable: 4723)
53  bool IntersectsBox(box3<T> const & Box, T * Intersection) const
54  {
55  T tmin = (Box.MinCorner.X - Origin.X) / Direction.X;
56  T tmax = (Box.MaxCorner.X - Origin.X) / Direction.X;
57 
58  if (tmin > tmax)
59  std::swap(tmin, tmax);
60 
61  T tymin = (Box.MinCorner.Y - Origin.Y) / Direction.Y;
62  T tymax = (Box.MaxCorner.Y - Origin.Y) / Direction.Y;
63 
64  if (tymin > tymax)
65  std::swap(tymin, tymax);
66 
67  if ((tmin > tymax) || (tymin > tmax))
68  return false;
69 
70  if (tymin > tmin)
71  tmin = tymin;
72  if (tymax < tmax)
73  tmax = tymax;
74 
75  T tzmin = (Box.MinCorner.Z - Origin.Z) / Direction.Z;
76  T tzmax = (Box.MaxCorner.Z - Origin.Z) / Direction.Z;
77 
78  if (tzmin > tzmax)
79  std::swap(tzmin, tzmax);
80 
81  if ((tmin > tzmax) || (tzmin > tmax))
82  return false;
83 
84  if (tzmin > tmin)
85  tmin = tzmin;
86  if (tzmax < tmax)
87  tmax = tzmax;
88 
89  if ((tmin > std::numeric_limits<T>::max()) || (tmax < 0))
90  return false;
91 
92  if (Intersection)
93  {
94  if (tmin > 0)
95  {
96  *Intersection = tmin;
97  }
98  else
99  {
100  *Intersection = tmax;
101  }
102  }
103  return true;
104  }
105 #pragma warning(default: 4723)
106 
107 #pragma warning(disable: 4723)
108  bool IntersectsBox(box3<T> const & Box) const
109  {
110  T tmin = (Box.MinCorner.X - Origin.X) / Direction.X;
111  T tmax = (Box.MaxCorner.X - Origin.X) / Direction.X;
112 
113  if (tmin > tmax)
114  std::swap(tmin, tmax);
115 
116  T tymin = (Box.MinCorner.Y - Origin.Y) / Direction.Y;
117  T tymax = (Box.MaxCorner.Y - Origin.Y) / Direction.Y;
118 
119  if (tymin > tymax)
120  std::swap(tymin, tymax);
121 
122  if ((tmin > tymax) || (tymin > tmax))
123  return false;
124 
125  if (tymin > tmin)
126  tmin = tymin;
127  if (tymax < tmax)
128  tmax = tymax;
129 
130  T tzmin = (Box.MinCorner.Z - Origin.Z) / Direction.Z;
131  T tzmax = (Box.MaxCorner.Z - Origin.Z) / Direction.Z;
132 
133  if (tzmin > tzmax)
134  std::swap(tzmin, tzmax);
135 
136  if ((tmin > tzmax) || (tzmin > tmax))
137  return false;
138 
139  if (tzmin > tmin)
140  tmin = tzmin;
141  if (tzmax < tmax)
142  tmax = tzmax;
143 
144  if ((tmin > std::numeric_limits<T>::max()) || (tmax < 0))
145  return false;
146 
147  return true;
148  }
149 #pragma warning(default: 4723)
150 
151  bool IntersectsSphere(vec3<T> const & Center, T const Radius, T * Intersection = nullptr) const
152  {
153  vec3<T> const OffsetOrigin = Origin - Center;
154  T const A = Dot(Direction, Direction);
155  T const B = Dot(Direction, OffsetOrigin);
156  T const C = Dot(OffsetOrigin, OffsetOrigin) - Radius*Radius;
157 
158  T const Discriminant = B * B - A * C;
159 
160  if (Discriminant >= 0.f)
161  {
162  T Dividend;
163  if (B < 0)
164  {
165  Dividend = -B + sqrt(Discriminant);
166  }
167  else
168  {
169  Dividend = -B - sqrt(Discriminant);
170  }
171 
172  T Parameter = C / Dividend;
173 
174  if (Parameter <= 0)
175  {
176  Parameter = Dividend / A;
177  }
178 
179  if (Parameter >= 0)
180  {
181  if (Intersection)
182  {
183  *Intersection = Parameter;
184  }
185  return true;
186  }
187  }
188 
189  return false;
190  }
191 
192  bool IntersectsTriangle(vec3f const & v0, vec3f const & v1, vec3f const & v2, T * Intersection) const
193  {
194  vec3f const p = Origin;
195  vec3f const d = Direction;
196 
197  vec3f e1, e2, h, s, q;
198 
199  float a, f, u, v;
200  e1 = v1 - v0;
201  e2 = v2 - v0;
202 
203  h = Cross(d, e2);
204  a = Dot(e1, h);
205 
206  if (a > -RoundingError32 && a < RoundingError32)
207  return false;
208 
209  f = 1 / a;
210  s = p - v0;
211  u = f * (Dot(s, h));
212 
213  if ((u < 0.f || u > 1.f) && ! Equals(u, 0.f) && ! Equals(u, 1.f))
214  return false;
215 
216  q = Cross(s, e1);
217  v = f * Dot(d, q);
218 
219  if ((v < 0.f || u + v > 1.f) && ! Equals(v, 0.f) && ! Equals(u + v, 1.f))
220  return false;
221 
222  float const t = f * Dot(e2, q);
223 
224  if (t >= 0.f || Equals(t, 0.f))
225  {
226  if (Intersection)
227  {
228  *Intersection = t;
229  }
230 
231  return true;
232  }
233  else
234  return false;
235  }
236 
237  bool operator == (ray3<T> const & other) const
238  {
239  return Origin == other.Origin && Direction == other.Direction;
240  }
241 
242  bool operator != (ray3<T> const & other) const
243  {
244  return Origin != other.Origin && Direction != other.Direction;
245  }
246 
247  friend std::ostream & operator << (std::ostream & stream, ray3<T> const & ray)
248  {
249  return stream << "{" << ray.Origin << "} -> {" << ray.Direction << "}";
250  }
251 
252  };
253 
256 
257 }
bool operator==(ray3< T > const &other) const
Definition: ray3.h:237
bool IntersectsBox(box3< T > const &Box) const
Definition: ray3.h:108
vec3< T > Direction
Definition: ray3.h:19
bool IntersectsSphere(vec3< T > const &Center, T const Radius, T *Intersection=nullptr) const
Definition: ray3.h:151
3D vector
Definition: vec3.h:15
bool IntersectsTriangle(vec3f const &v0, vec3f const &v1, vec3f const &v2, T *Intersection) const
Definition: ray3.h:192
bool operator!=(ray3< T > const &other) const
Definition: ray3.h:242
ray3< float > ray3f
Definition: ray3.h:254
void Transform(glm::mat4 const &mat, float const TranslateComponent=1)
Definition: vec3.h:587
vec3< T > GetPoint(T const Parameter) const
Definition: ray3.h:33
Vector MaxCorner
Definition: SBoundingBox3.h:21
ray3()
Definition: ray3.h:21
vec3< T > Origin
Definition: ray3.h:18
T Z
Definition: vec3.h:20
T X
Definition: vec3.h:18
bool IntersectsBox(box3< T > const &Box, T *Intersection) const
Definition: ray3.h:53
ray3 GetTransformed(glm::mat4 const &Matrix) const
Definition: ray3.h:44
Definition: CCatmullRomAdvancedSplineInterpolator.h:7
ray3(vec3< T > const &Origin, vec3< T > const &Direction)
Definition: ray3.h:27
ray3< double > ray3d
Definition: ray3.h:255
3D ray
Definition: ray3.h:13
Vector MinCorner
Definition: SBoundingBox3.h:21
void Transform(glm::mat4 const &Matrix)
Definition: ray3.h:38
3D axis-aligned bounding box
Definition: SBoundingBox3.h:14
float const RoundingError32
Global constant for 32bit floating-point epsilon.
Definition: ionComparison.h:22
vec3< T > GetTransformed(glm::mat4 const &mat, float const TranslateComponent=1) const
Definition: vec3.h:594
T Y
Definition: vec3.h:19