Plasma Engine  2.0
Loading...
Searching...
No Matches
AllClasses_inl.h
1#pragma once
2
3#include <Foundation/Math/BoundingBox.h>
4#include <Foundation/Math/BoundingSphere.h>
5#include <Foundation/Math/Mat3.h>
6#include <Foundation/Math/Mat4.h>
7#include <Foundation/Math/Plane.h>
8
9template <typename Type>
11{
12 return Contains(sphere.GetBoundingBox());
13}
14
15template <typename Type>
17{
18 // check whether the closest point between box and sphere is inside the sphere (it is definitely inside the box)
19 return sphere.Contains(GetClampedPoint(sphere.m_vCenter));
20}
21
22template <typename Type>
24{
25 return (GetClampedPoint(sphere.m_vCenter) - sphere.m_vCenter).GetLength() - sphere.m_fRadius;
26}
27
28template <typename Type>
30{
31 return plBoundingSphereTemplate<Type>::MakeFromCenterAndRadius(GetCenter(), (m_vMax - m_vMin).GetLength() * (Type)0.5);
32}
33
34template <typename Type>
36{
37 // compute the min and max extends of the AABB relative to the sphere (sphere center is the new origin)
38 const plVec3 vDiffMax = rhs.m_vMax - m_vCenter;
39 const plVec3 vDiffMin = rhs.m_vMin - m_vCenter;
40
41 // compute the absolute distance to each AABB extremum, per axis
42 const plVec3 vDiffMaxAbs(plMath::Abs(vDiffMax.x), plMath::Abs(vDiffMax.y), plMath::Abs(vDiffMax.z));
43 const plVec3 vDiffMinAbs(plMath::Abs(vDiffMin.x), plMath::Abs(vDiffMin.y), plMath::Abs(vDiffMin.z));
44
45 // take the maximum distance for each axis, to compute the point that is the farthest away from the sphere
46 const plVec3 vMostDistantPoint = vDiffMinAbs.CompMax(vDiffMaxAbs);
47
48 const Type fDistSQR = vMostDistantPoint.GetLengthSquared();
49
50 if (plMath::Square(m_fRadius) < fDistSQR)
51 m_fRadius = plMath::Sqrt(fDistSQR);
52}
53
54template <typename Type>
56{
57 const plVec3Template<Type> vPointOnBox = rhs.GetClampedPoint(m_vCenter);
58
59 return GetDistanceTo(vPointOnBox);
61
62template <typename Type>
64{
65 // compute the min and max extends of the AABB relative to the sphere (sphere center is the new origin)
66 const plVec3 vDiffMax = rhs.m_vMax - m_vCenter;
67 const plVec3 vDiffMin = rhs.m_vMin - m_vCenter;
68
69 // compute the absolute distance to each AABB extremum, per axis
70 const plVec3 vDiffMaxAbs(plMath::Abs(vDiffMax.x), plMath::Abs(vDiffMax.y), plMath::Abs(vDiffMax.z));
71 const plVec3 vDiffMinAbs(plMath::Abs(vDiffMin.x), plMath::Abs(vDiffMin.y), plMath::Abs(vDiffMin.z));
72
73 // take the maximum distance for each axis, to compute the point that is the farthest away from the sphere
74 const plVec3 vMostDistantPoint = vDiffMinAbs.CompMax(vDiffMaxAbs);
75
76 // if the squared length of that point is still smaller than the sphere radius, it is inside the sphere
77 // and thus the whole AABB is inside the sphere
78 return vMostDistantPoint.GetLengthSquared() <= m_fRadius * m_fRadius;
79}
80
81template <typename Type>
83{
84 return Contains(rhs.GetClampedPoint(m_vCenter));
85}
86
87template <typename Type>
89{
90 return plBoundingBoxTemplate<Type>::MakeFromMinMax(m_vCenter - plVec3Template<Type>(m_fRadius), m_vCenter + plVec3Template<Type>(m_fRadius));
94template <typename Type>
96{
97 const Type fDist = GetDistanceTo(sphere.m_vCenter);
98
99 if (fDist >= sphere.m_fRadius)
102 if (-fDist >= sphere.m_fRadius)
104
106}
107
108template <typename Type>
110{
111 plVec3Template<Type> vPos = box.m_vMin;
112 plVec3Template<Type> vNeg = box.m_vMax;
113
114 if (m_vNormal.x >= (Type)0)
115 {
116 vPos.x = box.m_vMax.x;
117 vNeg.x = box.m_vMin.x;
119
120 if (m_vNormal.y >= (Type)0)
121 {
122 vPos.y = box.m_vMax.y;
123 vNeg.y = box.m_vMin.y;
124 }
125
126 if (m_vNormal.z >= (Type)0)
127 {
128 vPos.z = box.m_vMax.z;
129 vNeg.z = box.m_vMin.z;
130 }
131
132 if (GetDistanceTo(vPos) <= (Type)0)
134
135 if (GetDistanceTo(vNeg) >= (Type)0)
137
139}
140
141template <typename Type>
143{
144 plVec3Template<Type> vNeg = box.m_vMax;
145
146 if (m_vNormal.x >= (Type)0)
147 {
148 vNeg.x = box.m_vMin.x;
149 }
150
151 if (m_vNormal.y >= (Type)0)
152 {
153 vNeg.y = box.m_vMin.y;
155
156 if (m_vNormal.z >= (Type)0)
157 {
158 vNeg.z = box.m_vMin.z;
159 }
160
161 return GetDistanceTo(vNeg);
162}
163
164template <typename Type>
166{
167 plVec3Template<Type> vPos = box.m_vMin;
168
169 if (m_vNormal.x >= (Type)0)
170 {
171 vPos.x = box.m_vMax.x;
172 }
173
174 if (m_vNormal.y >= (Type)0)
175 {
176 vPos.y = box.m_vMax.y;
177 }
178
179 if (m_vNormal.z >= (Type)0)
180 {
181 vPos.z = box.m_vMax.z;
182 }
183
184 return GetDistanceTo(vPos);
185}
186
187
188template <typename Type>
190{
191 PL_ASSERT_DEBUG(vAxis.IsNormalized(0.1f), "vAxis must be normalized.");
192
193 const Type cos = plMath::Cos(angle);
194 const Type sin = plMath::Sin(angle);
195 const Type oneminuscos = (Type)1 - cos;
196
197 const Type xy = vAxis.x * vAxis.y;
198 const Type xz = vAxis.x * vAxis.z;
199 const Type yz = vAxis.y * vAxis.z;
200
201 const Type xsin = vAxis.x * sin;
202 const Type ysin = vAxis.y * sin;
203 const Type zsin = vAxis.z * sin;
204
205 const Type onecos_xy = oneminuscos * xy;
206 const Type onecos_xz = oneminuscos * xz;
207 const Type onecos_yz = oneminuscos * yz;
208
210
211 // Column 1
212 res.Element(0, 0) = cos + (oneminuscos * (vAxis.x * vAxis.x));
213 res.Element(0, 1) = onecos_xy + zsin;
214 res.Element(0, 2) = onecos_xz - ysin;
215
216 // Column 2 )
217 res.Element(1, 0) = onecos_xy - zsin;
218 res.Element(1, 1) = cos + (oneminuscos * (vAxis.y * vAxis.y));
219 res.Element(1, 2) = onecos_yz + xsin;
220
221 // Column 3 )
222 res.Element(2, 0) = onecos_xz + ysin;
223 res.Element(2, 1) = onecos_yz - xsin;
224 res.Element(2, 2) = cos + (oneminuscos * (vAxis.z * vAxis.z));
225
226 return res;
227}
228
229template <typename Type>
231{
232 const Type fDet = Element(0, 0) * (Element(2, 2) * Element(1, 1) - Element(1, 2) * Element(2, 1)) -
233 Element(0, 1) * (Element(2, 2) * Element(1, 0) - Element(1, 2) * Element(2, 0)) +
234 Element(0, 2) * (Element(2, 1) * Element(1, 0) - Element(1, 1) * Element(2, 0));
235
236 if (plMath::IsZero(fDet, fEpsilon))
237 return PL_FAILURE;
238
239 const Type fOneDivDet = (Type)1 / fDet;
240
241 plMat3Template<Type> Inverse;
242
243 Inverse.Element(0, 0) = (Element(2, 2) * Element(1, 1) - Element(1, 2) * Element(2, 1));
244 Inverse.Element(0, 1) = -(Element(2, 2) * Element(0, 1) - Element(0, 2) * Element(2, 1));
245 Inverse.Element(0, 2) = (Element(1, 2) * Element(0, 1) - Element(0, 2) * Element(1, 1));
246
247 Inverse.Element(1, 0) = -(Element(2, 2) * Element(1, 0) - Element(1, 2) * Element(2, 0));
248 Inverse.Element(1, 1) = (Element(2, 2) * Element(0, 0) - Element(0, 2) * Element(2, 0));
249 Inverse.Element(1, 2) = -(Element(1, 2) * Element(0, 0) - Element(0, 2) * Element(1, 0));
250
251 Inverse.Element(2, 0) = (Element(2, 1) * Element(1, 0) - Element(1, 1) * Element(2, 0));
252 Inverse.Element(2, 1) = -(Element(2, 1) * Element(0, 0) - Element(0, 1) * Element(2, 0));
253 Inverse.Element(2, 2) = (Element(1, 1) * Element(0, 0) - Element(0, 1) * Element(1, 0));
254
255 *this = Inverse * fOneDivDet;
256 return PL_SUCCESS;
257}
258
259template <typename Type>
261{
262 PL_ASSERT_DEBUG(vAxis.IsNormalized(), "vAxis must be normalized.");
263
264 const Type cos = plMath::Cos(angle);
265 const Type sin = plMath::Sin(angle);
266 const Type oneminuscos = (Type)1 - cos;
267
268 const Type xy = vAxis.x * vAxis.y;
269 const Type xz = vAxis.x * vAxis.z;
270 const Type yz = vAxis.y * vAxis.z;
271
272 const Type xsin = vAxis.x * sin;
273 const Type ysin = vAxis.y * sin;
274 const Type zsin = vAxis.z * sin;
275
276 const Type onecos_xy = oneminuscos * xy;
277 const Type onecos_xz = oneminuscos * xz;
278 const Type onecos_yz = oneminuscos * yz;
279
281
282 // Column 1
283 res.Element(0, 0) = cos + (oneminuscos * (vAxis.x * vAxis.x));
284 res.Element(0, 1) = onecos_xy + zsin;
285 res.Element(0, 2) = onecos_xz - ysin;
286 res.Element(0, 3) = 0;
287
288 // Column 2
289 res.Element(1, 0) = onecos_xy - zsin;
290 res.Element(1, 1) = cos + (oneminuscos * (vAxis.y * vAxis.y));
291 res.Element(1, 2) = onecos_yz + xsin;
292 res.Element(1, 3) = 0;
293
294 // Column 3
295 res.Element(2, 0) = onecos_xz + ysin;
296 res.Element(2, 1) = onecos_yz - xsin;
297 res.Element(2, 2) = cos + (oneminuscos * (vAxis.z * vAxis.z));
298 res.Element(2, 3) = 0;
299
300 // Column 4
301 res.Element(3, 0) = 0;
302 res.Element(3, 1) = 0;
303 res.Element(3, 2) = 0;
304 res.Element(3, 3) = 1;
305
306 return res;
307}
308
309template <typename Type>
311{
312 plMat4Template<Type> Inverse;
313
314 const Type fDet = GetDeterminantOf4x4Matrix(*this);
315
316 if (plMath::IsZero(fDet, fEpsilon))
317 return PL_FAILURE;
318
319 Type fOneDivDet = plMath::Invert(fDet);
320
321 for (plInt32 i = 0; i < 4; ++i)
322 {
323
324 Inverse.Element(i, 0) = GetDeterminantOf3x3SubMatrix(*this, i, 0) * fOneDivDet;
325 fOneDivDet = -fOneDivDet;
326 Inverse.Element(i, 1) = GetDeterminantOf3x3SubMatrix(*this, i, 1) * fOneDivDet;
327 fOneDivDet = -fOneDivDet;
328 Inverse.Element(i, 2) = GetDeterminantOf3x3SubMatrix(*this, i, 2) * fOneDivDet;
329 fOneDivDet = -fOneDivDet;
330 Inverse.Element(i, 3) = GetDeterminantOf3x3SubMatrix(*this, i, 3) * fOneDivDet;
331 }
332
333 *this = Inverse;
334 return PL_SUCCESS;
335}
336
338
339// static
340template <typename T>
341bool plComparisonOperator::Compare(plComparisonOperator::Enum cmp, const T& a, const T& b)
342{
343 switch (cmp)
344 {
345 case plComparisonOperator::Equal:
346 return a == b;
347 case plComparisonOperator::NotEqual:
348 return !(a == b);
349 case plComparisonOperator::Less:
350 return a < b;
351 case plComparisonOperator::LessEqual:
352 return !(b < a);
353 case plComparisonOperator::Greater:
354 return b < a;
355 case plComparisonOperator::GreaterEqual:
356 return !(a < b);
357
358 PL_DEFAULT_CASE_NOT_IMPLEMENTED;
359 }
360
361 return false;
362}
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
An axis-aligned bounding box implementation.
Definition BoundingBox.h:12
Type GetDistanceTo(const plVec3Template< Type > &vPoint) const
Returns the minimum distance from the box's surface to the point. Zero if the point is inside the box...
Definition BoundingBox_inl.h:324
static plBoundingBoxTemplate< Type > MakeFromMinMax(const plVec3Template< Type > &vMin, const plVec3Template< Type > &vMax)
Creates a box with the given minimum and maximum values.
Definition BoundingBox_inl.h:42
const plVec3Template< Type > GetClampedPoint(const plVec3Template< Type > &vPoint) const
The given point is clamped to the volume of the box, i.e. it will be either inside the box or on its ...
Definition BoundingBox_inl.h:318
bool Contains(const plVec3Template< Type > &vPoint) const
Checks whether the given point is inside the box.
Definition BoundingBox_inl.h:162
bool Overlaps(const plBoundingBoxTemplate &rhs) const
Checks whether this box overlaps with the given box.
Definition BoundingBox_inl.h:197
const plBoundingSphereTemplate< Type > GetBoundingSphere() const
Returns a bounding sphere that encloses this box.
Definition AllClasses_inl.h:29
An implementation of a bounding sphere.
Definition BoundingSphere.h:11
static plBoundingSphereTemplate< Type > MakeFromCenterAndRadius(const plVec3Template< Type > &vCenter, Type fRadius)
Creates a sphere with the provided center and radius.
Definition BoundingSphere_inl.h:35
Type GetDistanceTo(const plVec3Template< Type > &vPoint) const
Computes the distance of the point to the sphere's surface. Returns negative values for points inside...
Definition BoundingSphere_inl.h:201
bool Overlaps(const plVec3Template< Type > *pPoints, plUInt32 uiNumPoints, plUInt32 uiStride=sizeof(plVec3Template< Type >)) const
Checks whether any of the given points is inside the sphere.
Definition BoundingSphere_inl.h:270
void ExpandToInclude(const plVec3Template< Type > &vPoint)
Increases the sphere's radius to include this point. Does NOT change its position,...
Definition BoundingSphere_inl.h:102
bool Contains(const plVec3Template< Type > &vPoint) const
Returns true if the given point is inside the sphere.
Definition BoundingSphere_inl.h:213
const plBoundingBoxTemplate< Type > GetBoundingBox() const
Returns a bounding box that encloses this sphere.
Definition AllClasses_inl.h:88
A 3x3 component matrix class.
Definition Mat3.h:9
static plMat3Template< Type > MakeAxisRotation(const plVec3Template< Type > &vAxis, plAngle angle)
Creates a matrix that is a rotation matrix around the given axis.
Definition AllClasses_inl.h:189
plResult Invert(Type fEpsilon=plMath::SmallEpsilon< Type >())
Inverts this matrix. Return value indicates whether the matrix could be Inverted.
Definition AllClasses_inl.h:230
A 4x4 component matrix class.
Definition Mat4.h:11
static plMat4Template< Type > MakeAxisRotation(const plVec3Template< Type > &vAxis, plAngle angle)
Creates a matrix that is a rotation matrix around the given axis.
Definition AllClasses_inl.h:260
plResult Invert(Type fEpsilon=plMath::SmallEpsilon< Type >())
Inverts this matrix. Return value indicates whether the matrix could be inverted.
Definition AllClasses_inl.h:310
PL_DECLARE_IF_FLOAT_TYPE bool IsNormalized(Type fEpsilon=plMath::HugeEpsilon< Type >()) const
Returns, whether the squared length of this vector is between 0.999f and 1.001f.
Definition Vec3_inl.h:121
Type GetLengthSquared() const
Returns the squared length. Faster, since no square-root is taken. Useful, if one only wants to compa...
Definition Vec3_inl.h:70
const plVec3Template< Type > CompMax(const plVec3Template< Type > &rhs) const
Returns the component-wise maximum of *this and rhs.
Definition Vec3_inl.h:326
constexpr PL_ALWAYS_INLINE T Square(T f)
Returns f * f.
Definition Math_inl.h:8
PL_ALWAYS_INLINE float Sin(plAngle a)
***** Trigonometric Functions *****
Definition MathFloat_inl.h:62
constexpr Type Invert(Type f)
Returns 1 / f.
Definition Math_inl.h:63
PL_ALWAYS_INLINE double Sqrt(double f)
Returns the square root of f.
Definition MathDouble_inl.h:99
bool IsZero(Type f, Type fEpsilon)
Checks whether the given number is close to zero.
Definition Math_inl.h:288
constexpr PL_ALWAYS_INLINE T Abs(T f)
Returns the absolute value of f.
Definition Math_inl.h:21
PL_ALWAYS_INLINE float Cos(plAngle a)
Takes an angle, returns its cosine.
Definition MathFloat_inl.h:67
static bool Compare(plComparisonOperator::Enum cmp, const T &a, const T &b)
Compares a to b with the given operator. This function only needs the == and < operator for T.
Definition AllClasses_inl.h:341
plPositionOnPlane::Enum GetObjectPosition(const plVec3Template< Type > *const pPoints, plUInt32 uiVertices) const
Returns on which side of the plane the set of points lies. Might be on both sides.
Definition Plane_inl.h:305
Type GetMaximumDistanceTo(const plBoundingBoxTemplate< Type > &box) const
Returns the maximum distance between given box and a plane.
Definition AllClasses_inl.h:165
Type GetMinimumDistanceTo(const plVec3Template< Type > *pPoints, plUInt32 uiNumPoints, plUInt32 uiStride=sizeof(plVec3Template< Type >)) const
Returns the minimum distance that any of the given points had to the plane.
Definition Plane_inl.h:431
Enum
Definition Plane.h:10
@ Spanning
Something is spanning a plane, i.e. some points are on the front and some on the back.
Definition Plane.h:14
@ Back
Something is completely on the back side of a plane.
Definition Plane.h:11
@ Front
Something is completely in front of a plane.
Definition Plane.h:12
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54