1#pragma once
2
3#include <Havok/Common/Base/Math/Vector/hkSimdFloat32.h>
4#include <Havok/Common/Base/Memory/Router/hkMemoryRouter.h>
5#include <Havok/Common/Base/Types/hkBaseDefs.h>
6#include <Havok/Common/Base/Types/hkBaseTypes.h>
7
8#ifndef HK_MATH_H
9#error "Include <Havok/Common/Base/Math/hkMath.h> or hkBase.h"
10#endif
11
12class hkVector4f {
13public:
14 HK_DECLARE_CLASS_ALLOCATOR(hkVector4f)
15
16 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,modernize-use-equals-default)
17 HK_FORCE_INLINE hkVector4f() {}
18 HK_FORCE_INLINE hkVector4f(hkFloat32 x, hkFloat32 y, hkFloat32 z, hkFloat32 w = 0);
19 HK_FORCE_INLINE hkVector4f(const hkVector4f& other);
20 HK_FORCE_INLINE hkVector4f& operator=(hkVector4fParameter other);
21
22 // ========== Vector initialization
23
24 HK_FORCE_INLINE void set(hkFloat32 x, hkFloat32 y, hkFloat32 z, hkFloat32 w = 0);
25 HK_FORCE_INLINE void setXYZ(hkVector4fParameter xyz);
26 HK_FORCE_INLINE void setXYZ_W(hkVector4fParameter xyz, hkSimdFloat32Parameter w);
27 HK_FORCE_INLINE void setAll(hkFloat32 x);
28 HK_FORCE_INLINE void setAll(hkSimdFloat32Parameter x);
29 HK_FORCE_INLINE void setZero();
30 template <int I>
31 HK_FORCE_INLINE void zeroComponent();
32 HK_FORCE_INLINE void zeroComponent(int i);
33
34 // ========== Vector operations
35
36 HK_FORCE_INLINE void add(hkVector4fParameter a);
37 HK_FORCE_INLINE void sub(hkVector4fParameter a);
38 HK_FORCE_INLINE void mul(hkVector4fParameter a);
39 HK_FORCE_INLINE void div(hkVector4fParameter a);
40
41 HK_FORCE_INLINE void setAdd(hkVector4fParameter a, hkVector4fParameter b);
42 HK_FORCE_INLINE void setSub(hkVector4fParameter a, hkVector4fParameter b);
43 HK_FORCE_INLINE void setMul(hkVector4fParameter a, hkVector4fParameter b);
44 HK_FORCE_INLINE void setDiv(hkVector4fParameter a, hkVector4fParameter b);
45
46 HK_FORCE_INLINE void add(hkSimdFloat32Parameter a);
47 HK_FORCE_INLINE void sub(hkSimdFloat32Parameter a);
48 HK_FORCE_INLINE void mul(hkSimdFloat32Parameter a);
49 HK_FORCE_INLINE void setMul(hkVector4fParameter a, hkSimdFloat32Parameter r);
50 HK_FORCE_INLINE void setMul(hkSimdFloat32Parameter r, hkVector4fParameter a);
51 HK_FORCE_INLINE void setAdd(hkVector4fParameter a, hkSimdFloat32Parameter b);
52 HK_FORCE_INLINE void setSub(hkVector4fParameter a, hkSimdFloat32Parameter b);
53
54 HK_FORCE_INLINE void setReciprocal(hkVector4fParameter a);
55 HK_FORCE_INLINE void setSqrt(hkVector4fParameter a);
56 HK_FORCE_INLINE void setSqrtInverse(hkVector4fParameter a);
57
58 HK_FORCE_INLINE void addMul(hkVector4fParameter a, hkVector4fParameter b);
59 HK_FORCE_INLINE void subMul(hkVector4fParameter a, hkVector4fParameter b);
60
61 HK_FORCE_INLINE void setAddMul(hkVector4fParameter a, hkVector4fParameter b,
62 hkVector4fParameter c);
63 HK_FORCE_INLINE void setSubMul(hkVector4fParameter a, hkVector4fParameter b,
64 hkVector4fParameter c);
65
66 HK_FORCE_INLINE void addMul(hkVector4fParameter a, hkSimdFloat32Parameter r);
67 HK_FORCE_INLINE void addMul(hkSimdFloat32Parameter r, hkVector4fParameter a);
68 HK_FORCE_INLINE void subMul(hkVector4fParameter a, hkSimdFloat32Parameter r);
69 HK_FORCE_INLINE void subMul(hkSimdFloat32Parameter r, hkVector4fParameter a);
70
71 HK_FORCE_INLINE void setAddMul(hkVector4fParameter a, hkVector4fParameter b,
72 hkSimdFloat32Parameter r);
73 HK_FORCE_INLINE void setSubMul(hkVector4fParameter a, hkVector4fParameter b,
74 hkSimdFloat32Parameter r);
75
76 HK_FORCE_INLINE void setCross(hkVector4fParameter a, hkVector4fParameter b);
77 HK_FORCE_INLINE void setInterpolate(hkVector4fParameter v0, hkVector4fParameter v1,
78 hkSimdFloat32Parameter t);
79
80 // ========== Comparisons
81
82 HK_FORCE_INLINE hkVector4fComparison less(hkVector4fParameter a) const;
83 HK_FORCE_INLINE hkVector4fComparison lessEqual(hkVector4fParameter a) const;
84 HK_FORCE_INLINE hkVector4fComparison greater(hkVector4fParameter a) const;
85 HK_FORCE_INLINE hkVector4fComparison greaterEqual(hkVector4fParameter a) const;
86 HK_FORCE_INLINE hkVector4fComparison equal(hkVector4fParameter a) const;
87 HK_FORCE_INLINE hkVector4fComparison notEqual(hkVector4fParameter a) const;
88 HK_FORCE_INLINE hkVector4fComparison lessZero() const;
89 HK_FORCE_INLINE hkVector4fComparison lessEqualZero() const;
90 HK_FORCE_INLINE hkVector4fComparison greaterZero() const;
91 HK_FORCE_INLINE hkVector4fComparison greaterEqualZero() const;
92 HK_FORCE_INLINE hkVector4fComparison equalZero() const;
93 HK_FORCE_INLINE hkVector4fComparison notEqualZero() const;
94
95 /// Whether the first N components of this vector are within `epsilon`
96 /// of the corresponding components in `v`.
97 template <int N>
98 HK_FORCE_INLINE hkBool32 allEqual(hkVector4fParameter rhs,
99 hkSimdFloat32Parameter epsilon) const;
100
101 // ========== Sign, comparisons, clamping
102
103 HK_FORCE_INLINE void setAbs(hkVector4fParameter a);
104 template <int N>
105 HK_FORCE_INLINE void setNeg(hkVector4fParameter a);
106
107 /// v[i] = mask[i] ? -a[i] : a[i]
108 HK_FORCE_INLINE void setFlipSign(hkVector4fParameter a, hkVector4fComparisonParameter mask);
109 /// v[i] = signs[i] < 0 ? -a[i] : a[i]
110 HK_FORCE_INLINE void setFlipSign(hkVector4fParameter a, hkVector4fParameter signs);
111 /// v[i] = sign < 0 ? -a[i] : a[i]
112 HK_FORCE_INLINE void setFlipSign(hkVector4fParameter a, hkSimdFloat32Parameter sign);
113
114 /// Whether the sign bit is set. (True for -0.0.)
115 HK_FORCE_INLINE hkVector4fComparison signBitSet() const;
116 /// Whether the sign bit is cleared.
117 HK_FORCE_INLINE hkVector4fComparison signBitClear() const;
118
119 // ========== Matrix operations (out-of-line)
120
121 void setRotatedDir(const hkMatrix3f& a, hkVector4fParameter b);
122 void setRotatedInverseDir(const hkMatrix3f& a, hkVector4fParameter b);
123 void setTransformedPos(const hkTransformf& a, const hkVector4f& pos);
124 void setTransformedInversePos(const hkTransformf& a, hkVector4fParameter b);
125
126 void setRotatedDir(hkQuaternionfParameter quat, hkVector4fParameter direction);
127 void setRotatedInverseDir(hkQuaternionfParameter quat, hkVector4fParameter direction);
128 void setTransformedPos(const hkQsTransformf& a, hkVector4fParameter b);
129 void setTransformedInversePos(const hkQsTransformf& a, hkVector4fParameter b);
130
131 void setTransformedPos(const hkQTransformf& a, hkVector4fParameter b);
132 void setTransformedInversePos(const hkQTransformf& a, hkVector4fParameter b);
133
134 // ========== Matrix operations (inline)
135
136 HK_FORCE_INLINE void _setRotatedDir(const hkMatrix3f& a, hkVector4fParameter b);
137 HK_FORCE_INLINE void _setRotatedDir(hkQuaternionfParameter quat, hkVector4fParameter vec);
138 HK_FORCE_INLINE void _setRotatedInverseDir(hkQuaternionfParameter quat,
139 hkVector4fParameter vec);
140 HK_FORCE_INLINE void _setTransformedPos(const hkTransformf& a, hkVector4fParameter b);
141
142 // ========== Length and normalization
143
144 template <int N>
145 HK_FORCE_INLINE hkSimdFloat32 dot(hkVector4fParameter a) const;
146
147 template <int N>
148 HK_FORCE_INLINE void setDot(hkVector4fParameter a, hkVector4fParameter b);
149
150 /// Get the length of this vector as if it had N components.
151 template <int N>
152 HK_FORCE_INLINE hkSimdFloat32 length() const;
153
154 /// Get the squared length (|v|^2) of this vector as if it had N components.
155 template <int N>
156 HK_FORCE_INLINE hkSimdFloat32 lengthSquared() const;
157
158 /// Get the inverse length (1/|v|) of this vector as if it had N components.
159 template <int N>
160 HK_FORCE_INLINE hkSimdFloat32 lengthInverse() const;
161
162 /// Get the inverse length (1/|v|) of this vector as if it had N components.
163 /// Does not check for negative sqrt values or divide-by-zero.
164 template <int N>
165 HK_FORCE_INLINE hkSimdFloat32 lengthInverseUnsafe() const;
166
167 /// Normalize this vector as if it had N components.
168 template <int N>
169 HK_FORCE_INLINE void normalize();
170
171 /// Normalize this vector as if it had N components.
172 /// Does not check for negative sqrt values or divide-by-zero.
173 template <int N>
174 HK_FORCE_INLINE void normalizeUnsafe();
175
176 // ========== Misc
177
178 /// Dot product of this vector and (a.x, a.y, a.z, 1).
179 hkSimdFloat32 dot4xyz1(hkVector4fParameter a) const;
180
181 // ========== Component access
182
183 hkFloat32& operator()(int i) { return reinterpret_cast<float*>(&v)[i]; }
184 hkFloat32& operator[](int i) { return reinterpret_cast<float*>(&v)[i]; }
185 const hkFloat32& operator()(int i) const { return reinterpret_cast<const float*>(&v)[i]; }
186 const hkFloat32& operator[](int i) const { return reinterpret_cast<const float*>(&v)[i]; }
187
188 template <int I>
189 HK_FORCE_INLINE hkSimdFloat32 getComponent() const {
190 return v[I];
191 }
192 hkSimdFloat32 getComponent(int i) const { return v[i]; }
193 hkSimdFloat32 getX() const { return getComponent<0>(); }
194 hkSimdFloat32 getY() const { return getComponent<1>(); }
195 hkSimdFloat32 getZ() const { return getComponent<2>(); }
196 hkSimdFloat32 getW() const { return getComponent<3>(); }
197 template <int I>
198 HK_FORCE_INLINE void setComponent(hkSimdFloat32Parameter val) {
199 v[I] = val;
200 }
201 void setComponent(int i, hkSimdFloat32Parameter val) { v[i] = val; }
202 void setX(hkSimdFloat32Parameter val) { setComponent(0, val); }
203 void setY(hkSimdFloat32Parameter val) { setComponent(1, val); }
204 void setZ(hkSimdFloat32Parameter val) { setComponent(2, val); }
205 void setW(hkSimdFloat32Parameter val) { setComponent(3, val); }
206
207 HK_FORCE_INLINE void setInt24W(int value);
208 HK_FORCE_INLINE int getInt24W() const;
209
210 // ========== Load/store
211
212 template <int Constant>
213 HK_FORCE_INLINE static const hkVector4f& getConstant();
214
215 HK_FORCE_INLINE static hkVector4f zero() {
216 hkVector4f u;
217 u.setZero();
218 return u;
219 }
220
221 /// Load N floats from in.
222 template <int N>
223 void load(const hkFloat32* in);
224
225 /// Store N floats to out.
226 template <int N>
227 void store(hkFloat32* out) const;
228
229 m128 v;
230};
231