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