Plasma Engine  2.0
Loading...
Searching...
No Matches
SimdBSphere_inl.h
1#pragma once
2
3PL_ALWAYS_INLINE plSimdBSphere::plSimdBSphere() = default;
4
5PL_ALWAYS_INLINE plSimdBSphere::plSimdBSphere(const plSimdVec4f& vCenter, const plSimdFloat& fRadius)
6 : m_CenterAndRadius(vCenter)
7{
8 m_CenterAndRadius.SetW(fRadius);
9}
10
12{
13 plSimdBSphere res;
14 res.m_CenterAndRadius = plSimdVec4f::MakeZero();
15 return res;
16}
17
18PL_ALWAYS_INLINE plSimdBSphere plSimdBSphere::MakeInvalid(const plSimdVec4f& vCenter /*= plSimdVec4f::MakeZero()*/)
19{
20 plSimdBSphere res;
21 res.m_CenterAndRadius.Set(0.0f, 0.0f, 0.0f, -plMath::SmallEpsilon<float>());
22 return res;
23}
24
25PL_ALWAYS_INLINE plSimdBSphere plSimdBSphere::MakeFromCenterAndRadius(const plSimdVec4f& vCenter, const plSimdFloat& fRadius)
26{
27 return plSimdBSphere(vCenter, fRadius);
28}
29
30inline plSimdBSphere plSimdBSphere::MakeFromPoints(const plSimdVec4f* pPoints, plUInt32 uiNumPoints, plUInt32 uiStride /*= sizeof(plSimdVec4f)*/)
31{
32 PL_ASSERT_DEBUG(pPoints != nullptr, "The array must not be empty.");
33 PL_ASSERT_DEBUG(uiStride >= sizeof(plSimdVec4f), "The data must not overlap.");
34 PL_ASSERT_DEBUG(uiNumPoints > 0, "The array must contain at least one point.");
35
36 plSimdBSphere res;
37
38 const plSimdVec4f* pCur = pPoints;
39
41 for (plUInt32 i = 0; i < uiNumPoints; ++i)
42 {
43 vCenter += *pCur;
44 pCur = plMemoryUtils::AddByteOffset(pCur, uiStride);
45 }
46
47 res.m_CenterAndRadius = vCenter / plSimdFloat(uiNumPoints);
48
49 pCur = pPoints;
50
51 plSimdFloat fMaxDistSquare = plSimdFloat::MakeZero();
52 for (plUInt32 i = 0; i < uiNumPoints; ++i)
53 {
54 const plSimdFloat fDistSQR = (*pCur - res.m_CenterAndRadius).GetLengthSquared<3>();
55 fMaxDistSquare = fMaxDistSquare.Max(fDistSQR);
56
57 pCur = plMemoryUtils::AddByteOffset(pCur, uiStride);
58 }
59
60 res.m_CenterAndRadius.SetW(fMaxDistSquare.GetSqrt());
61
62 return res;
63}
64
65PL_ALWAYS_INLINE void plSimdBSphere::SetInvalid()
66{
67 m_CenterAndRadius.Set(0.0f, 0.0f, 0.0f, -plMath::SmallEpsilon<float>());
68}
69
70PL_ALWAYS_INLINE bool plSimdBSphere::IsValid() const
71{
72 return m_CenterAndRadius.IsValid<4>() && GetRadius() >= plSimdFloat::MakeZero();
73}
74
75PL_ALWAYS_INLINE bool plSimdBSphere::IsNaN() const
76{
77 return m_CenterAndRadius.IsNaN<4>();
78}
79
80PL_ALWAYS_INLINE plSimdVec4f plSimdBSphere::GetCenter() const
81{
82 return m_CenterAndRadius;
83}
84
85PL_ALWAYS_INLINE plSimdFloat plSimdBSphere::GetRadius() const
86{
87 return m_CenterAndRadius.w();
88}
89
90PL_ALWAYS_INLINE void plSimdBSphere::SetFromPoints(const plSimdVec4f* pPoints, plUInt32 uiNumPoints, plUInt32 uiStride)
91{
92 *this = MakeFromPoints(pPoints, uiNumPoints, uiStride);
93}
94
95PL_ALWAYS_INLINE void plSimdBSphere::ExpandToInclude(const plSimdVec4f& vPoint)
96{
97 const plSimdFloat fDist = (vPoint - m_CenterAndRadius).GetLength<3>();
98
99 m_CenterAndRadius.SetW(fDist.Max(GetRadius()));
100}
101
102inline void plSimdBSphere::ExpandToInclude(const plSimdVec4f* pPoints, plUInt32 uiNumPoints, plUInt32 uiStride)
103{
104 PL_ASSERT_DEBUG(pPoints != nullptr, "The array must not be empty.");
105 PL_ASSERT_DEBUG(uiStride >= sizeof(plSimdVec4f), "The data must not overlap.");
106
107 const plSimdVec4f* pCur = pPoints;
108
109 plSimdFloat fMaxDistSquare = plSimdFloat::MakeZero();
110
111 for (plUInt32 i = 0; i < uiNumPoints; ++i)
112 {
113 const plSimdFloat fDistSQR = (*pCur - m_CenterAndRadius).GetLengthSquared<3>();
114 fMaxDistSquare = fMaxDistSquare.Max(fDistSQR);
115
116 pCur = plMemoryUtils::AddByteOffset(pCur, uiStride);
117 }
118
119 m_CenterAndRadius.SetW(fMaxDistSquare.GetSqrt().Max(GetRadius()));
120}
121
122PL_ALWAYS_INLINE void plSimdBSphere::ExpandToInclude(const plSimdBSphere& rhs)
123{
124 const plSimdFloat fReqRadius = (rhs.m_CenterAndRadius - m_CenterAndRadius).GetLength<3>() + rhs.GetRadius();
125
126 m_CenterAndRadius.SetW(fReqRadius.Max(GetRadius()));
127}
128
130{
131 plSimdVec4f newCenterAndRadius = t.TransformPosition(m_CenterAndRadius);
132 newCenterAndRadius.SetW(t.GetMaxScale() * GetRadius());
133
134 m_CenterAndRadius = newCenterAndRadius;
135}
136
137inline void plSimdBSphere::Transform(const plSimdMat4f& mMat)
138{
139 plSimdFloat radius = m_CenterAndRadius.w();
140 m_CenterAndRadius = mMat.TransformPosition(m_CenterAndRadius);
141
142 plSimdFloat maxRadius = mMat.m_col0.Dot<3>(mMat.m_col0);
143 maxRadius = maxRadius.Max(mMat.m_col1.Dot<3>(mMat.m_col1));
144 maxRadius = maxRadius.Max(mMat.m_col2.Dot<3>(mMat.m_col2));
145 radius *= maxRadius.GetSqrt();
146
147 m_CenterAndRadius.SetW(radius);
148}
149
150PL_ALWAYS_INLINE plSimdFloat plSimdBSphere::GetDistanceTo(const plSimdVec4f& vPoint) const
151{
152 return (vPoint - m_CenterAndRadius).GetLength<3>() - GetRadius();
153}
154
156{
157 return (rhs.m_CenterAndRadius - m_CenterAndRadius).GetLength<3>() - GetRadius() - rhs.GetRadius();
158}
159
160PL_ALWAYS_INLINE bool plSimdBSphere::Contains(const plSimdVec4f& vPoint) const
161{
162 plSimdFloat radius = GetRadius();
163 return (vPoint - m_CenterAndRadius).GetLengthSquared<3>() <= (radius * radius);
164}
165
166PL_ALWAYS_INLINE bool plSimdBSphere::Contains(const plSimdBSphere& rhs) const
167{
168 return (rhs.m_CenterAndRadius - m_CenterAndRadius).GetLength<3>() + rhs.GetRadius() <= GetRadius();
169}
170
171PL_ALWAYS_INLINE bool plSimdBSphere::Overlaps(const plSimdBSphere& rhs) const
172{
173 plSimdFloat radius = (rhs.m_CenterAndRadius + m_CenterAndRadius).w();
174 return (rhs.m_CenterAndRadius - m_CenterAndRadius).GetLengthSquared<3>() < (radius * radius);
175}
176
178{
179 plSimdVec4f vDir = vPoint - m_CenterAndRadius;
180 plSimdFloat fDist = vDir.GetLengthAndNormalize<3>().Min(GetRadius());
181
182 return m_CenterAndRadius + (vDir * fDist);
183}
184
185PL_ALWAYS_INLINE bool plSimdBSphere::operator==(const plSimdBSphere& rhs) const
186{
187 return (m_CenterAndRadius == rhs.m_CenterAndRadius).AllSet();
188}
189
190PL_ALWAYS_INLINE bool plSimdBSphere::operator!=(const plSimdBSphere& rhs) const
191{
192 return (m_CenterAndRadius != rhs.m_CenterAndRadius).AnySet();
193}
static T * AddByteOffset(T *pPtr, std::ptrdiff_t offset)
Returns the address stored in ptr plus the given byte offset iOffset, cast to type T.
Definition SimdBSphere.h:6
plSimdFloat GetRadius() const
Returns the radius.
Definition SimdBSphere_inl.h:85
plSimdFloat GetDistanceTo(const plSimdVec4f &vPoint) const
Computes the distance of the point to the sphere's surface. Returns negative values for points inside...
Definition SimdBSphere_inl.h:150
static plSimdBSphere MakeFromPoints(const plSimdVec4f *pPoints, plUInt32 uiNumPoints, plUInt32 uiStride=sizeof(plSimdVec4f))
Creates a bounding sphere around the provided points.
Definition SimdBSphere_inl.h:30
plSimdBSphere()
Default constructor does not initialize any data.
void Transform(const plSimdTransform &t)
Transforms the sphere in its local space.
Definition SimdBSphere_inl.h:129
void ExpandToInclude(const plSimdVec4f &vPoint)
Increases the sphere's radius to include this point.
Definition SimdBSphere_inl.h:95
bool Contains(const plSimdVec4f &vPoint) const
Returns true if the given point is inside the sphere.
Definition SimdBSphere_inl.h:160
static plSimdBSphere MakeInvalid(const plSimdVec4f &vCenter=plSimdVec4f::MakeZero())
Creates an 'invalid' sphere, with its center at the given position and a negative radius.
Definition SimdBSphere_inl.h:18
void SetInvalid()
Sets the bounding sphere to invalid values.
Definition SimdBSphere_inl.h:65
bool Overlaps(const plSimdBSphere &rhs) const
Checks whether the two objects overlap.
Definition SimdBSphere_inl.h:171
plSimdVec4f GetClampedPoint(const plSimdVec4f &vPoint)
Clamps the given position to the volume of the sphere. The resulting point will always be inside the ...
Definition SimdBSphere_inl.h:177
plSimdVec4f GetCenter() const
Returns the center.
Definition SimdBSphere_inl.h:80
static plSimdBSphere MakeFromCenterAndRadius(const plSimdVec4f &vCenter, const plSimdFloat &fRadius)
Creates a sphere with the provided center and radius.
Definition SimdBSphere_inl.h:25
void SetFromPoints(const plSimdVec4f *pPoints, plUInt32 uiNumPoints, plUInt32 uiStride=sizeof(plSimdVec4f))
Initializes the sphere to be the bounding sphere of all the given points.
Definition SimdBSphere_inl.h:90
bool IsNaN() const
Returns whether any value is NaN.
Definition SimdBSphere_inl.h:75
bool IsValid() const
Returns whether the sphere has valid values.
Definition SimdBSphere_inl.h:70
static plSimdBSphere MakeZero()
Creates a sphere at the origin with radius zero.
Definition SimdBSphere_inl.h:11
Definition SimdFloat.h:7
static plSimdFloat MakeZero()
Creates an plSimdFloat that is initialized to zero.
Definition FPUFloat_inl.h:36
A 4x4 matrix class.
Definition SimdMat4f.h:7
plSimdVec4f TransformPosition(const plSimdVec4f &v) const
Matrix-vector multiplication, assuming the 4th component of the vector is one (default behavior).
Definition SimdMat4f_inl.h:141
Definition SimdTransform.h:6
plSimdFloat GetMaxScale() const
Returns the scale component with maximum magnitude.
Definition SimdTransform_inl.h:54
A 4-component SIMD vector class.
Definition SimdVec4f.h:8
static plSimdVec4f MakeZero()
Creates an plSimdVec4f that is initialized to zero.
Definition SimdVec4f_inl.h:8