nlib
SimdVector3.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_SIMD_SIMDVECTOR3_H_
17 #define INCLUDE_NN_NLIB_SIMD_SIMDVECTOR3_H_
18 
19 #include "nn/nlib/simd/SimdFloat.h"
22 
23 NLIB_NAMESPACE_BEGIN
24 namespace simd {
25 
27  public:
28  static SimdVector __vectorcall LoadFloat3(const Float3* p) NLIB_NOEXCEPT;
29  template<typename MyVector3>
30  static SimdVector __vectorcall LoadFloat3(const MyVector3* p) NLIB_NOEXCEPT;
31  static void __vectorcall StoreFloat3(Float3* p, SimdVectorArg vec) NLIB_NOEXCEPT;
32  template<typename MyVector3>
33  static void __vectorcall StoreFloat3(MyVector3* p, SimdVectorArg vec) NLIB_NOEXCEPT;
34  static bool __vectorcall CmpEq(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
35  static bool __vectorcall CmpLt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
36  static bool __vectorcall CmpLe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
37  static bool __vectorcall CmpGt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
38  static bool __vectorcall CmpGe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
39  static bool __vectorcall CmpNe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
40  static bool __vectorcall
41  CmpNearEq(SimdVectorArg vec1, SimdVectorArg vec2, SimdVectorArg eps) NLIB_NOEXCEPT;
42  static bool __vectorcall IsNaN(SimdVectorArg vec) NLIB_NOEXCEPT;
43  static bool __vectorcall IsInfinite(SimdVectorArg vec) NLIB_NOEXCEPT;
44  static bool __vectorcall InBound(SimdVectorArg vec, SimdVectorArg bounds) NLIB_NOEXCEPT;
45  static f128 __vectorcall Dot(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
46  template <bool SetLane0, bool SetLane1, bool SetLane2, bool SetLane3>
47  static f128 __vectorcall DotEx(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
48  static SimdVector __vectorcall Cross(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
49  static SimdVector __vectorcall Normalize(SimdVectorArg vec) NLIB_NOEXCEPT;
50  static SimdVector __vectorcall NormalizeEst(SimdVectorArg vec) NLIB_NOEXCEPT;
51  static float __vectorcall Normalize(SimdVector* normalized,
53  static float __vectorcall NormalizeEst(SimdVector* normalized,
55  static f128 __vectorcall LengthSq(SimdVectorArg vec) NLIB_NOEXCEPT;
56  static f128 __vectorcall Length(SimdVectorArg vec) NLIB_NOEXCEPT;
57  static f128 __vectorcall LengthEst(SimdVectorArg vec) NLIB_NOEXCEPT;
58  static f128 __vectorcall RecpLength(SimdVectorArg vec) NLIB_NOEXCEPT;
59  static f128 __vectorcall RecpLengthEst(SimdVectorArg vec) NLIB_NOEXCEPT;
60  static f128 __vectorcall GetAngle(SimdVectorArg vec1_normalized,
61  SimdVectorArg vec2_normalized) NLIB_NOEXCEPT;
62  static SimdVector __vectorcall Reflect(SimdVectorArg vec, SimdVectorArg normal) NLIB_NOEXCEPT;
63  static SimdVector __vectorcall Orthogonal(SimdVector vec) NLIB_NOEXCEPT; // not implemented yet
64 
65  static SimdVector __vectorcall Transform(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT;
66  static SimdVector __vectorcall
67  TransformCoord(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT;
68  static SimdVector __vectorcall
69  TransformNormal(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT;
70 
71  static SimdVector __vectorcall
72  Rotate(SimdVectorArg vec, SimdQuaternionArg q_normalized) NLIB_NOEXCEPT;
73  static SimdVector __vectorcall
74  InvRotate(SimdVectorArg vec, SimdQuaternionArg q_normalized) NLIB_NOEXCEPT;
75 
76  // Transform****Stream
77  // Project, Unproject
78 
79  private:
80  Vector3(); // forbidden
81 };
82 
83 #ifndef NLIB_DOXYGEN
84 
85 #define NLIB_M(tp) inline tp __vectorcall
86 #define NLIB_MH(tp) inline tp __vectorcall
87 
88 // p is 4 bytes aligned
89 NLIB_M(SimdVector) Vector3::LoadFloat3(const Float3* p) NLIB_NOEXCEPT {
90 #ifdef NLIB_F128_SIMD_NOUSE
91  f128 ret;
92  ret.vec.v[0] = p->x;
93  ret.vec.v[1] = p->y;
94  ret.vec.v[2] = p->z;
95  ret.vec.v[3] = 0.f;
96  return ret;
97 #elif defined(NLIB_SSE41)
98  __m128 x = _mm_load_ss(&p->x);
99  __m128 y = _mm_load_ss(&p->y);
100  __m128 z = _mm_load_ss(&p->z);
101  __m128 xy = _mm_unpacklo_ps(x, y);
102  return _mm_shuffle_ps(xy, z, _MM_SHUFFLE(1, 0, 1, 0));
103 #elif defined(NLIB_NEON)
104  float32x2_t xy = vld1_f32(&p->x);
105  float32x2_t z = vld1_lane_f32(&p->z, xy, 0);
106  return vcombine_f32(xy, z);
107 #elif defined(CAFE)
108  f128 ret;
109  ret.vec.ps[0][0] = p->x;
110  ret.vec.ps[0][1] = p->y;
111  ret.vec.ps[1][0] = p->z;
112  return ret;
113 #endif
114 }
115 
116 template<typename MyVector3>
117 // MyVector is a structure like 'struct MyVector3 { float x, y, z; };'
118 // DirectX::XMFLOAT3, DirectX::XMFLOAT3A for example
119 NLIB_MH(SimdVector) Vector3::LoadFloat3(const MyVector3* p) NLIB_NOEXCEPT {
120  NLIB_STATIC_ASSERT(sizeof(p->x) == 4);
121  NLIB_STATIC_ASSERT(sizeof(p->y) == 4);
122  NLIB_STATIC_ASSERT(sizeof(p->z) == 4);
123  return Vector3::LoadFloat3(reinterpret_cast<const Float3*>(&p->x));
124 }
125 
126 // p is 4 bytes aligned
127 NLIB_M(void) Vector3::StoreFloat3(Float3* p, SimdVectorArg vec) NLIB_NOEXCEPT { // NOLINT
128 #ifdef NLIB_F128_SIMD_NOUSE
129  p->x = vec.vec.v[0];
130  p->y = vec.vec.v[1];
131  p->z = vec.vec.v[2];
132 #elif defined(NLIB_SSE41)
133  f128 y = _mm_shuffle_ps(vec, vec, _MM_SHUFFLE(1, 1, 1, 1));
134  f128 z = _mm_shuffle_ps(vec, vec, _MM_SHUFFLE(2, 2, 2, 2));
135  _mm_store_ss(&p->x, vec);
136  _mm_store_ss(&p->y, y);
137  _mm_store_ss(&p->z, z);
138 #elif defined(NLIB_NEON)
139  float32x2_t lo = vget_low_f32(vec);
140  vst1_f32(&p->x, lo);
141  vst1q_lane_f32(&p->z, vec, 2);
142 #elif defined(CAFE)
143  p->x = vec.vec.ps[0][0];
144  p->y = vec.vec.ps[0][1];
145  p->z = vec.vec.ps[1][0];
146 #endif
147 }
148 
149 template<typename MyVector3>
150 NLIB_MH(void) Vector3::StoreFloat3(MyVector3* p, SimdVectorArg vec) NLIB_NOEXCEPT { // NOLINT
151  // MyVector is a structure like 'struct MyVector3 { float x, y, z; };'
152  // DirectX::XMFLOAT3, DirectX::XMFLOAT3A for example
153  NLIB_STATIC_ASSERT(sizeof(p->x) == 4);
154  NLIB_STATIC_ASSERT(sizeof(p->y) == 4);
155  NLIB_STATIC_ASSERT(sizeof(p->z) == 4);
156  Vector3::StoreFloat3(reinterpret_cast<Float3*>(&p->x), vec);
157 }
158 
159 // true if vec1[xyz] == vec2[xyz]
160 inline bool __vectorcall Vector3::CmpEq(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
161  f128 mask = F128::CmpEq(vec1, vec2);
162  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
163 }
164 
165 // true if vec1[xyz] < vec2[xyz]
166 inline bool __vectorcall Vector3::CmpLt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
167  f128 mask = F128::CmpLt(vec1, vec2);
168  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
169 }
170 
171 // true if vec1[xyz] <= vec2[xyz]
172 inline bool __vectorcall Vector3::CmpLe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
173  f128 mask = F128::CmpLe(vec1, vec2);
174  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
175 }
176 
177 // true if vec1[xyz] > vec2[xyz]
178 inline bool __vectorcall Vector3::CmpGt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
179  f128 mask = F128::CmpGt(vec1, vec2);
180  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
181 }
182 
183 // true if vec1[xyz] >= vec2[xyz]
184 inline bool __vectorcall Vector3::CmpGe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
185  f128 mask = F128::CmpGe(vec1, vec2);
186  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
187 }
188 
189 // vec1.x != vec2.x || vec1.y != vec2.y || vec1.z != vec2.z
190 inline bool __vectorcall Vector3::CmpNe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
191  f128 mask = F128::CmpNe(vec1, vec2);
192  return !F128::IsAllMaskFalse(F128::Swizzle<0, 1, 2, 2>(mask));
193 }
194 
195 inline bool __vectorcall
196 Vector3::CmpNearEq(SimdVectorArg vec1, SimdVectorArg vec2, SimdVectorArg eps) NLIB_NOEXCEPT {
197  f128 mask = F128::CmpNearEq(vec1, vec2, eps);
198  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
199 }
200 
201 // isnan(vec.x) || isnan(vec.y) || isnan(vec.z)
202 inline bool __vectorcall Vector3::IsNaN(SimdVectorArg vec) NLIB_NOEXCEPT {
203  f128 mask = F128::IsNaN(vec);
204  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
205 }
206 
207 // isinf(vec.x) || isinf(vec.y) || isinf(vec.z)
208 inline bool __vectorcall Vector3::IsInfinite(SimdVectorArg vec) NLIB_NOEXCEPT {
209  f128 mask = F128::IsInfinite(vec);
210  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
211 }
212 
213 // true if abs(vec[xyz]) <= bounds[xyz]
214 inline bool __vectorcall Vector3::InBound(SimdVectorArg vec, SimdVectorArg bounds) NLIB_NOEXCEPT {
215  f128 mask = F128::InBound(vec, bounds);
216  return F128::IsAllMaskTrue(F128::Swizzle<0, 1, 2, 2>(mask));
217 }
218 
219 // r = { dot, dot, dot, dot }
220 NLIB_M(f128) Vector3::Dot(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
221 #ifdef NLIB_F128_SIMD_NOUSE
222  float tmp = vec1.vec.v[0] * vec2.vec.v[0] + vec1.vec.v[1] * vec2.vec.v[1] +
223  vec1.vec.v[2] * vec2.vec.v[2];
224  f128 rval;
225  rval.vec.v[0] = rval.vec.v[1] = rval.vec.v[2] = rval.vec.v[3] = tmp;
226  return rval;
227 #elif defined(NLIB_SSE41)
228  return _mm_dp_ps(vec1, vec2, 0x7F);
229 #elif defined(NLIB_NEON)
230 #ifdef __aarch64__
231  float32x4_t tmp = vmulq_f32(vec1, vec2);
232  tmp = F128::Permute<0, 1, 2, 6>(tmp, vdupq_n_f32(0.f));
233  tmp = vpaddq_f32(tmp, tmp);
234  tmp = vpaddq_f32(tmp, tmp);
235  return tmp;
236 #else
237  f128 tmp = vmulq_f32(vec1, vec2);
238  float32x2_t lo = vget_low_f32(tmp);
239  lo = vpadd_f32(lo, lo);
240  float32x2_t hi = vdup_lane_f32(vget_high_f32(tmp), 0);
241  lo = vadd_f32(lo, hi);
242  return vcombine_f32(lo, lo);
243 #endif
244 #elif defined(CAFE)
245  f128 tmp = F128::Mult(vec1, vec2);
246  f32x2 val = __PS_SUM0(tmp.vec.ps[0], tmp.vec.ps[0], tmp.vec.ps[0]);
247  val = __PS_ADD(val, tmp.vec.ps[1]);
248  f128 ret;
249  ret.vec.ps[0] = ret.vec.ps[1] = __PS_FDUP(val[0]);
250  return ret;
251 #endif
252 }
253 
254 template <bool SetLane0, bool SetLane1, bool SetLane2, bool SetLane3>
255 // r[i] = SetLane[i] ? dot : 0.f
256 NLIB_MH(f128) Vector3::DotEx(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
257 #if !defined(NLIB_F128_SIMD_NOUSE) && defined(NLIB_SSE41)
258  return _mm_dp_ps(vec1, vec2,
259  (0x70 | (SetLane0 ? 1 : 0) | (SetLane1 ? 2 : 0) |
260  (SetLane2 ? 4 : 0) | (SetLane3 ? 8 : 0)));
261 #else
262  return F128::Splat<SetLane0, SetLane1, SetLane2, SetLane3>(F128::SetZero(), Dot(vec1, vec2));
263 #endif
264 }
265 
266 // 'w' component is arbitrary
267 NLIB_M(SimdVector) Vector3::Cross(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
268  SimdVector rval = F128::Mult(F128::Swizzle<1, 2, 0, -1>(vec1),
269  F128::Swizzle<2, 0, 1, -1>(vec2));
270  // yz, zx, xy, *
271  rval = F128::MultSub(F128::Swizzle<2, 0, 1, -1>(vec1), F128::Swizzle<1, 2, 0, -1>(vec2), rval);
272  // yz - zy, zx - xz, xy - yx, *
273  return rval;
274 }
275 
276 // nan if |vec| is too big, 0 if |vec| = 0
277 NLIB_M(SimdVector) Vector3::Normalize(SimdVectorArg vec) NLIB_NOEXCEPT {
278  f128 dot = Vector3::Dot(vec, vec);
279 #if defined(NLIB_NEON) && !defined(NLIB_F128_SIMD_NOUSE)
280  float32x4_t x;
281  x = vrsqrteq_f32(dot);
282  x = vmulq_f32(x, vrsqrtsq_f32(dot, vmulq_f32(x, x)));
283  f128 rsqrt = vmulq_f32(x, vrsqrtsq_f32(dot, vmulq_f32(x, x)));
284 #else
285  f128 rsqrt = F128::RecpSqrt(dot);
286 #endif
287  f128 inf = F128::SetInfinity();
288  f128 eqzero = F128::CmpEqZero(dot);
289  f128 eqinf = F128::CmpEq(dot, inf);
290  SimdVector ret = F128::Mult(vec, rsqrt);
291  f128 nan = F128::SetNaN();
292  ret = F128::AndNot(eqzero, ret);
293  ret = F128::Select(eqinf, nan, ret);
294  return ret;
295 }
296 
297 NLIB_M(float) Vector3::Normalize(SimdVector* normalized, SimdVectorArg vec) NLIB_NOEXCEPT {
298  f128 dot = Vector3::Dot(vec, vec);
299  f128 rsqrt = F128::RecpSqrt(dot);
300  *normalized = F128::Mult(vec, rsqrt);
301  return F128::GetFloatFromLane<0>(dot);
302 }
303 
304 // r = { lensq, lensq, lensq, lensq }
305 NLIB_M(f128) Vector3::LengthSq(SimdVectorArg vec) NLIB_NOEXCEPT { return Dot(vec, vec); }
306 
307 // r = { len, len, len, len }
308 NLIB_M(f128) Vector3::Length(SimdVectorArg vec) NLIB_NOEXCEPT {
309  return F128::Sqrt(Dot(vec, vec));
310 }
311 
312 // r = { len, len, len, len }
313 NLIB_M(f128) Vector3::LengthEst(SimdVectorArg vec) NLIB_NOEXCEPT {
314  return F128::SqrtEst(Dot(vec, vec));
315 }
316 
317 // r = { recpLen, recpLen, recpLen, recpLen }
318 NLIB_M(f128) Vector3::RecpLength(SimdVectorArg vec) NLIB_NOEXCEPT {
319  return F128::RecpSqrt(Dot(vec, vec));
320 }
321 
322 // r = { recpLen, recpLen, recpLen, recpLen }
323 NLIB_M(f128) Vector3::RecpLengthEst(SimdVectorArg vec) NLIB_NOEXCEPT {
324  return F128::RecpSqrtEst(Dot(vec, vec));
325 }
326 
327 NLIB_M(SimdVector) Vector3::NormalizeEst(SimdVectorArg vec) NLIB_NOEXCEPT {
328  return F128::Mult(vec, RecpLengthEst(vec));
329 }
330 
331 NLIB_M(float) Vector3::NormalizeEst(SimdVector* normalized, SimdVectorArg vec) NLIB_NOEXCEPT {
332  f128 dot = Vector3::Dot(vec, vec);
333  f128 rsqrt = F128::RecpSqrtEst(dot);
334  *normalized = F128::Mult(vec, rsqrt);
335  return F128::GetFloatFromLane<0>(dot);
336 }
337 
338 // { radian, radian, radian, radian }
339 NLIB_M(f128) Vector3::GetAngle(SimdVectorArg vec1_normalized,
340  SimdVectorArg vec2_normalized) NLIB_NOEXCEPT {
341  f128 ret = Dot(vec1_normalized, vec2_normalized);
342  ret = F128::Clamp(ret, F128::SetNegativeOne(), F128::SetOne());
343  return F128::ArcCos(ret);
344 }
345 
346 NLIB_M(SimdVector) Vector3::Reflect(SimdVectorArg vec, SimdVectorArg normal) NLIB_NOEXCEPT {
347  f128 s = Dot(vec, normal);
348  s = F128::Add(s, s);
349  return F128::MultSub(s, normal, vec);
350 }
351 
352 /*
353 // Vector3::Transform(vec, m) is better in performance
354 NLIB_M(SimdVector) Vector3::Transform(SimdMatrixArg m, SimdVectorArg vec) NLIB_NOEXCEPT {
355  f128 v = F128::SetFloatToLane<3>(vec, 1.f);
356  return Vector4::Transform(m, v);
357 }
358 */
359 
360 // r = { vec.x, vec.y, vec.z, 1 } * m
361 NLIB_M(SimdVector) Vector3::Transform(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT {
362  f128 ret = F128::Mult<0>(vec, m.r[0], each_select32);
363  ret = F128::MultAdd<1>(vec, m.r[1], ret, each_select32);
364  ret = F128::MultAdd<2>(vec, m.r[2], ret, each_select32);
365  return F128::Add(m.r[3], ret);
366 }
367 
368 // r = { vec.x, vec.y, vec.z, 1.f } * m, r = r / r.w
369 NLIB_M(SimdVector) Vector3::TransformCoord(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT {
370  f128 tmp = Vector3::Transform(vec, m);
371  return F128::Div(tmp, F128::SetValue<3>(tmp, each_select32));
372 }
373 
374 /*
375 // Vector3::TransformNormal(vec, m) is better in performance
376 NLIB_M(SimdVector) Vector3::TransformNormal(SimdMatrixArg m, SimdVectorArg vec) NLIB_NOEXCEPT {
377  f128 v = F128::SetZeroToLane<3>(vec);
378  return Vector4::Transform(m, v);
379 }
380 */
381 
382 // r = { vec.x, vec.y, vec.z, 0 } * m
383 NLIB_M(SimdVector) Vector3::TransformNormal(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT {
384  f128 ret = F128::Mult<0>(vec, m.r[0], each_select32);
385  ret = F128::MultAdd<1>(vec, m.r[1], ret, each_select32);
386  ret = F128::MultAdd<2>(vec, m.r[2], ret, each_select32);
387  return ret;
388 }
389 
390 NLIB_M(SimdVector) Vector3::Rotate(SimdVectorArg vec,
391  SimdQuaternionArg q_normalized) NLIB_NOEXCEPT {
392  SimdVector v = F128::SetZeroToLane<3>(vec);
393  SimdQuaternion conj = Quaternion::Conjugate(q_normalized);
394  return Quaternion::Mult(Quaternion::Mult(conj, v), q_normalized);
395 }
396 
397 NLIB_M(SimdVector) Vector3::InvRotate(SimdVectorArg vec,
398  SimdQuaternionArg q_normalized) NLIB_NOEXCEPT {
399  SimdVector v = F128::SetZeroToLane<3>(vec);
400  SimdQuaternion conj = Quaternion::Conjugate(q_normalized);
401  return Quaternion::Mult(Quaternion::Mult(q_normalized, v), conj);
402 }
403 
404 #undef NLIB_M
405 #undef NLIB_MH
406 
407 #endif // NLIB_DOXYGEN
408 
409 } // namespace simd
410 NLIB_NAMESPACE_END
411 
412 #endif // INCLUDE_NN_NLIB_SIMD_SIMDVECTOR3_H_
float x
The x-coordinate of the 3D vector.
Definition: SimdFloat.h:4290
Defines a quaternion.
f128arg SimdVectorArg
f128arg is defined using typedef.
Definition: SimdFloat.h:4148
#define NLIB_VIS_HIDDEN
Symbols for functions and classes are not made available outside of the library.
Definition: Platform_unix.h:88
f128arg SimdQuaternionArg
f128arg is defined using typedef.
Definition: SimdFloat.h:4150
The class with the collection of functions that perform calculations on three-dimensional vectors...
Definition: SimdVector3.h:26
f128 r[4]
Keeps each row of a 4x4 matrix.
Definition: SimdFloat.h:4175
The structure for keeping a 4x4 matrix.
Definition: SimdFloat.h:4159
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:99
Defines the class and functions for SIMD computations on single-precision floating-point numbers...
The type for reading and writing three-dimensional vectors in memory. Keeps float-type x...
Definition: SimdFloat.h:4289
constexpr const each_select32_tag each_select32
The tag for representing the selection of a 32-bit lane with an each_select32_tag-type constant objec...
Definition: SimdInt.h:63
float y
The y-coordinate of the 3D vector.
Definition: SimdFloat.h:4291
nlib_f128_t f128
nlib_f128_t is defined using typedef.
Definition: SimdFloat.h:71
float z
The z-coordinate of the 3D vector.
Definition: SimdFloat.h:4292
#define NLIB_STATIC_ASSERT(exp)
Defines a static assertion. Uses static_assert if it is available for use.
Definition: Config.h:154
Defines a four-dimensional vector.
f128 SimdQuaternion
f128 is defined using typedef. Used when handling quaternions.
Definition: SimdFloat.h:4149
f128 SimdVector
f128 is defined using typedef. Used when handling three-dimensional or four-dimensional vectors...
Definition: SimdFloat.h:4147