Newton Dynamics  4.00
ndVectorArmNeon.h
1 /* Copyright (c) <2003-2022> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __ND_VECTOR_ARM_NEON_H__
23 #define __ND_VECTOR_ARM_NEON_H__
24 
25 #include <arm_neon.h>
26 
27 #ifndef D_SCALAR_VECTOR_CLASS
28 
29 #ifdef D_NEWTON_USE_DOUBLE
30  #define ndVector ndBigVector
31 #else
32 
33 class ndBigVector;
34 // *****************************************************************************************
35 //
36 // 4 x 1 single precision vector class declaration
37 //
38 // *****************************************************************************************
39 D_MSV_NEWTON_ALIGN_16
40 class ndVector
41 {
42  public:
43  D_OPERATOR_NEW_AND_DELETE
44 
45  inline ndVector()
46  {
47  }
48 
49  inline ndVector(ndFloat32 val)
50  :m_type(vmovq_n_f32(val))
51  {
52  }
53 
54  inline ndVector(const ndVector& v)
55  :m_type(v.m_type)
56  {
57  }
58 
59  inline ndVector(const float32x4_t type)
60  :m_type(type)
61  {
62  }
63 
64  inline ndVector(const ndFloat32* const ptr)
65  :m_type(vld1q_f32 (ptr))
66  {
67  ndAssert(ndCheckVector((*this)));
68  }
69 
70  inline ndVector(const ndFloat32* const baseAddr, const ndInt32* const index)
71  :m_x(baseAddr[index[0]])
72  ,m_y(baseAddr[index[1]])
73  ,m_z(baseAddr[index[2]])
74  ,m_w(baseAddr[index[3]])
75  {
76  }
77 
78 
79 #ifndef D_NEWTON_USE_DOUBLE
80  inline ndVector(const ndFloat64* const ptr)
81  :m_x(ndFloat32(ptr[0]))
82  ,m_y(ndFloat32(ptr[1]))
83  ,m_z(ndFloat32(ptr[2]))
84  ,m_w(ndFloat32(ptr[3]))
85  {
86  }
87 #endif
88 
89  inline ndVector(ndFloat32 x, ndFloat32 y, ndFloat32 z, ndFloat32 w)
90  :m_x(x), m_y(y), m_z(z), m_w(w)
91  {
92  ndAssert(ndCheckVector((*this)));
93  }
94 
95  inline ndVector(ndInt32 ix, ndInt32 iy, ndInt32 iz, ndInt32 iw)
96  :m_ix(ix), m_iy(iy), m_iz(iz), m_iw(iw)
97  {
98  }
99 
100 #ifndef D_NEWTON_USE_DOUBLE
101  inline ndVector(const ndBigVector& copy)
102  :m_x(ndFloat32(((ndFloat64*)&copy)[0]))
103  ,m_y(ndFloat32(((ndFloat64*)&copy)[1]))
104  ,m_z(ndFloat32(((ndFloat64*)&copy)[2]))
105  ,m_w(ndFloat32(((ndFloat64*)&copy)[3]))
106  {
107  ndAssert(ndCheckVector((*this)));
108  }
109 #endif
110 
111  inline ndFloat32 GetScalar() const
112  {
113  return m_x;
114  }
115 
116  inline void Store(ndFloat32* const dst) const
117  {
118  vst1q_f32(dst, m_type);
119  }
120 
121  inline ndVector BroadcastX() const
122  {
123  return ndVector(m_x);
124  }
125 
126  inline ndVector BroadcastY() const
127  {
128  return ndVector(m_y);
129  }
130 
131  inline ndVector BroadcastZ() const
132  {
133  return ndVector(m_z);
134  }
135 
136  inline ndVector BroadcastW() const
137  {
138  return ndVector(m_w);
139  }
140 
141  inline ndFloat32& operator[] (ndInt32 i)
142  {
143  ndAssert(i < 4);
144  ndAssert(i >= 0);
145  return (&m_x)[i];
146  }
147 
148  inline const ndFloat32& operator[] (ndInt32 i) const
149  {
150  ndAssert(i < 4);
151  ndAssert(i >= 0);
152  return (&m_x)[i];
153  }
154 
155  inline ndVector operator+ (const ndVector& A) const
156  {
157  return vaddq_f32(m_type, A.m_type);
158  }
159 
160  inline ndVector operator- (const ndVector& A) const
161  {
162  return vsubq_f32(m_type, A.m_type);
163  }
164 
165  inline ndVector operator* (const ndVector& A) const
166  {
167  return vmulq_f32(m_type, A.m_type);
168  }
169 
170  inline ndVector& operator+= (const ndVector& A)
171  {
172  return (*this = vaddq_f32(m_type, A.m_type));
173  }
174 
175  inline ndVector& operator-= (const ndVector& A)
176  {
177  return (*this = vsubq_f32(m_type, A.m_type));
178  }
179 
180  inline ndVector& operator*= (const ndVector& A)
181  {
182  return (*this = vmulq_f32(m_type, A.m_type));
183  }
184 
185  inline ndVector MulAdd(const ndVector& A, const ndVector& B) const
186  {
187  //return *this + A * B;
188  return vmlaq_f32(m_type, A.m_type, B.m_type);
189  }
190 
191  inline ndVector MulSub(const ndVector& A, const ndVector& B) const
192  {
193  //return *this - A * B;
194  return vmlsq_f32(m_type, A.m_type, B.m_type);
195  }
196 
197  inline ndVector AddHorizontal() const
198  {
199  return ndVector(m_x + m_y + m_z + m_w);
200  }
201 
202  inline ndVector Scale(ndFloat32 scale) const
203  {
204  return ndVector(m_x * scale, m_y * scale, m_z * scale, m_w * scale);
205  }
206 
207  // return cross product
208  inline ndVector CrossProduct(const ndVector& B) const
209  {
210  return ndVector(
211  m_y * B.m_z - m_z * B.m_y,
212  m_z * B.m_x - m_x * B.m_z,
213  m_x * B.m_y - m_y * B.m_x, m_w);
214  }
215 
216  inline ndVector CrossProduct(const ndVector& A, const ndVector& B) const
217  {
218  ndFloat32 cofactor[3][3];
219  ndFloat32 array[4][4];
220 
221  const ndVector& me = *this;
222  for (ndInt32 i = 0; i < 4; ++i)
223  {
224  array[0][i] = me[i];
225  array[1][i] = A[i];
226  array[2][i] = B[i];
227  array[3][i] = ndFloat32(1.0f);
228  }
229 
230  ndVector normal;
231  ndFloat32 sign = ndFloat32(-1.0f);
232  for (ndInt32 i = 0; i < 4; ++i)
233  {
234  for (ndInt32 j = 0; j < 3; ++j)
235  {
236  ndInt32 k0 = 0;
237  for (ndInt32 k = 0; k < 4; ++k)
238  {
239  if (k != i)
240  {
241  cofactor[j][k0] = array[j][k];
242  k0++;
243  }
244  }
245  }
246  ndFloat32 x = cofactor[0][0] * (cofactor[1][1] * cofactor[2][2] - cofactor[1][2] * cofactor[2][1]);
247  ndFloat32 y = cofactor[0][1] * (cofactor[1][2] * cofactor[2][0] - cofactor[1][0] * cofactor[2][2]);
248  ndFloat32 z = cofactor[0][2] * (cofactor[1][0] * cofactor[2][1] - cofactor[1][1] * cofactor[2][0]);
249  ndFloat32 det = x + y + z;
250 
251  normal[i] = sign * det;
252  sign *= ndFloat32(-1.0f);
253  }
254 
255  return normal;
256  }
257 
258  inline ndVector GetInt() const
259  {
260  return ndVector(ndInt32(ndFloor(m_x)), ndInt32(ndFloor(m_y)), ndInt32(ndFloor(m_z)), ndInt32(ndFloor(m_w)));
261  }
262 
263  inline ndVector TestZero() const
264  {
265  const ndInt32* const a = (ndInt32*)&m_x;
266  return ndVector(
267  (a[0] == 0) ? ndFloat32(-1.0f) : ndFloat32(0.0f),
268  (a[1] == 0) ? ndFloat32(-1.0f) : ndFloat32(0.0f),
269  (a[2] == 0) ? ndFloat32(-1.0f) : ndFloat32(0.0f),
270  (a[3] == 0) ? ndFloat32(-1.0f) : ndFloat32(0.0f));
271  }
272 
273  inline ndVector Floor() const
274  {
275  return ndVector(ndFloor(m_x), ndFloor(m_y), ndFloor(m_z), ndFloor(m_w));
276  }
277 
278  inline ndVector DotProduct(const ndVector &A) const
279  {
280  //return ndVector(m_x * A.m_x + m_y * A.m_y + m_z * A.m_z + m_w * A.m_w);
281  return (*this * A).AddHorizontal();
282  }
283 
284  inline ndVector Reciproc() const
285  {
286  return ndVector(ndFloat32(1.0f) / m_x, ndFloat32(1.0f) / m_y, ndFloat32(1.0f) / m_z, ndFloat32(1.0f) / m_w);
287  }
288 
289  inline ndVector Sqrt() const
290  {
291  return ndVector(ndSqrt(m_x), ndSqrt(m_y), ndSqrt(m_z), ndSqrt(m_w));
292  }
293 
294  inline ndVector InvSqrt() const
295  {
296  return ndVector(ndRsqrt(m_x), ndRsqrt(m_y), ndRsqrt(m_z), ndRsqrt(m_w));
297  }
298 
299  inline ndVector InvMagSqrt() const
300  {
301  return ndVector(ndRsqrt(DotProduct(*this).m_x));
302  }
303 
304  inline ndVector Normalize() const
305  {
306  const ndVector& me = *this;
307  return me * InvMagSqrt();
308  }
309 
310  inline ndVector Abs() const
311  {
312  return vabsq_f32(m_type);
313  }
314 
315  inline ndVector GetMax() const
316  {
317  return ndVector(ndMax(ndMax(m_x, m_y), ndMax(m_z, m_w)));
318  }
319 
320  inline ndVector GetMax(const ndVector& data) const
321  {
322  return vmaxq_f32(m_type, data.m_type);
323  }
324 
325  inline ndVector GetMin(const ndVector& data) const
326  {
327  return vminq_f32(m_type, data.m_type);
328  }
329 
330  // relational operators
331  inline ndVector operator== (const ndVector& data) const
332  {
333  return vceqq_f32(m_typeInt, data.m_typeInt);
334  }
335 
336  inline ndVector operator> (const ndVector& data) const
337  {
338  return vcgtq_f32(m_typeInt, data.m_typeInt);
339  }
340 
341  inline ndVector operator< (const ndVector& data) const
342  {
343  return vcltq_f32(m_typeInt, data.m_typeInt);
344  }
345 
346  inline ndVector operator>= (const ndVector& data) const
347  {
348  return vcgeq_f32(m_typeInt, data.m_typeInt);
349  }
350 
351  inline ndVector operator<= (const ndVector& data) const
352  {
353  return vcleq_f32(m_typeInt, data.m_typeInt);
354  }
355 
356  // logical operations
357  inline ndVector operator& (const ndVector& data) const
358  {
359  return vandq_u32(m_typeInt, data.m_typeInt);
360  }
361 
362  inline ndVector operator| (const ndVector& data) const
363  {
364  return vorrq_u32(m_typeInt, data.m_typeInt);
365  }
366 
367  inline ndVector operator^ (const ndVector& data) const
368  {
369  return veorq_u32(m_typeInt, data.m_typeInt);
370  }
371 
372  inline ndVector AndNot(const ndVector& data) const
373  {
374  return vbicq_u32(m_typeInt, data.m_typeInt);
375  }
376 
377  inline ndVector Select(const ndVector& data, const ndVector& mask) const
378  {
379  // (((b ^ a) & mask)^a)
380  return (*this) ^ (mask & (data ^ (*this)));
381  }
382 
383  inline ndInt32 GetSignMask() const
384  {
385  const ndInt32* const a = (ndInt32*)&m_x;
386  return (((a[0] & 0x80000000) ? 1 : 0) | ((a[1] & 0x80000000) ? 2 : 0) | ((a[2] & 0x80000000) ? 4 : 0) | ((a[3] & 0x80000000) ? 8 : 0));
387  }
388 
389  inline ndVector ShiftRight() const
390  {
391  return ndVector(m_w, m_x, m_y, m_z);
392  }
393 
394  inline ndVector ShiftTripleRight() const
395  {
396  return ndVector(m_z, m_x, m_y, m_w);
397  }
398 
399  inline ndVector ShiftTripleLeft() const
400  {
401  return ndVector(m_y, m_z, m_x, m_w);
402  }
403 
404  inline ndVector ShiftRightLogical(ndInt32 bits) const
405  {
406  return ndVector(ndInt32(ndUnsigned32(m_ix) >> bits), ndInt32(ndUnsigned32(m_iy) >> bits), ndInt32(ndUnsigned32(m_iz) >> bits), ndInt32(ndUnsigned32(m_iw) >> bits));
407  }
408 
409  inline static void Transpose4x4(ndVector& dst0, ndVector& dst1, ndVector& dst2, ndVector& dst3, const ndVector& src0, const ndVector& src1, const ndVector& src2, const ndVector& src3)
410  {
411  float32x4x2_t vtrn1 = vzipq_f32(src0.m_type, src2.m_type);
412  float32x4x2_t vtrn2 = vzipq_f32(src1.m_type, src3.m_type);
413  float32x4x2_t res1 = vzipq_f32(vtrn1.val[0], vtrn2.val[0]);
414  float32x4x2_t res2 = vzipq_f32(vtrn1.val[1], vtrn2.val[1]);
415  dst0.m_type = res1.val[0];
416  dst1.m_type = res1.val[1];
417  dst2.m_type = res2.val[0];
418  dst3.m_type = res2.val[1];
419  }
420 
421  union
422  {
423  ndFloat32 m_f[4];
424  ndInt32 m_i[4];
425  float32x4_t m_type;
426  uint32x4_t m_typeInt;
427  struct
428  {
429  ndFloat32 m_x;
430  ndFloat32 m_y;
431  ndFloat32 m_z;
432  ndFloat32 m_w;
433  };
434  struct
435  {
436  ndInt32 m_ix;
437  ndInt32 m_iy;
438  ndInt32 m_iz;
439  ndInt32 m_iw;
440  };
441  };
442 
443  D_CORE_API static ndVector m_zero;
444  D_CORE_API static ndVector m_one;
445  D_CORE_API static ndVector m_wOne;
446  D_CORE_API static ndVector m_half;
447  D_CORE_API static ndVector m_two;
448  D_CORE_API static ndVector m_three;
449  D_CORE_API static ndVector m_negOne;
450  D_CORE_API static ndVector m_xMask;
451  D_CORE_API static ndVector m_yMask;
452  D_CORE_API static ndVector m_zMask;
453  D_CORE_API static ndVector m_wMask;
454  D_CORE_API static ndVector m_xyzwMask;
455  D_CORE_API static ndVector m_epsilon;
456  D_CORE_API static ndVector m_signMask;
457  D_CORE_API static ndVector m_triplexMask;
458 } D_GCC_NEWTON_ALIGN_16;
459 #endif
460 
461 D_MSV_NEWTON_ALIGN_32
463 {
464  public:
465  D_OPERATOR_NEW_AND_DELETE
466 
467  inline ndBigVector()
468  {
469  }
470 
471  inline ndBigVector(ndFloat64 val)
472  :m_x(val), m_y(val), m_z(val), m_w(val)
473  {
474  }
475 
476  inline ndBigVector(const ndBigVector& v)
477  : m_x(v.m_x), m_y(v.m_y), m_z(v.m_z), m_w(v.m_w)
478  {
479  }
480 
481 #ifndef D_NEWTON_USE_DOUBLE
482  inline ndBigVector(const ndVector& v)
483  : m_x(v.m_x), m_y(v.m_y), m_z(v.m_z), m_w(v.m_w)
484  {
485  }
486 
487  inline ndBigVector(const ndFloat32* const ptr)
488  : m_x(ptr[0]), m_y(ptr[1]), m_z(ptr[2]), m_w(ndFloat32(0.0f))
489  {
490  ndAssert(ndCheckVector((*this)));
491  }
492 #endif
493 
494  inline ndBigVector(const ndFloat64* const ptr)
495  :m_x(ptr[0]), m_y(ptr[1]), m_z(ptr[2]), m_w(ptr[3])
496  {
497  ndAssert(ndCheckVector((*this)));
498  }
499 
500  inline ndBigVector(ndFloat64 x, ndFloat64 y, ndFloat64 z, ndFloat64 w)
501  : m_x(x), m_y(y), m_z(z), m_w(w)
502  {
503  ndAssert(ndCheckVector((*this)));
504  }
505 
506  inline ndBigVector(ndInt32 ix, ndInt32 iy, ndInt32 iz, ndInt32 iw)
507  : m_ix(ix), m_iy(iy), m_iz(iz), m_iw(iw)
508  {
509  }
510 
511  inline ndBigVector(ndInt64 ix, ndInt64 iy, ndInt64 iz, ndInt64 iw)
512  : m_ix(ix), m_iy(iy), m_iz(iz), m_iw(iw)
513  {
514  }
515 
516  inline ndFloat64 GetScalar() const
517  {
518  return m_x;
519  }
520 
521  inline void Store(ndFloat64* const dst) const
522  {
523  dst[0] = m_x;
524  dst[1] = m_y;
525  dst[2] = m_z;
526  dst[3] = m_w;
527  }
528 
529  inline ndBigVector BroadcastX() const
530  {
531  return ndBigVector(m_x);
532  }
533 
534  inline ndBigVector BroadcastY() const
535  {
536  return ndBigVector(m_y);
537  }
538 
539  inline ndBigVector BroadcastZ() const
540  {
541  return ndBigVector(m_z);
542  }
543 
544  inline ndBigVector BroadcastW() const
545  {
546  return ndBigVector(m_w);
547  }
548 
549  inline ndFloat64& operator[] (ndInt32 i)
550  {
551  ndAssert(i < 4);
552  ndAssert(i >= 0);
553  return (&m_x)[i];
554  }
555 
556  inline const ndFloat64& operator[] (ndInt32 i) const
557  {
558  ndAssert(i < 4);
559  ndAssert(i >= 0);
560  return (&m_x)[i];
561  }
562 
563  inline ndBigVector operator+ (const ndBigVector& A) const
564  {
565  return ndBigVector(m_x + A.m_x, m_y + A.m_y, m_z + A.m_z, m_w + A.m_w);
566  }
567 
568  inline ndBigVector operator- (const ndBigVector& A) const
569  {
570  return ndBigVector(m_x - A.m_x, m_y - A.m_y, m_z - A.m_z, m_w - A.m_w);
571  }
572 
573  inline ndBigVector operator* (const ndBigVector& A) const
574  {
575  return ndBigVector(m_x * A.m_x, m_y * A.m_y, m_z * A.m_z, m_w * A.m_w);
576  }
577 
578  inline ndBigVector& operator+= (const ndBigVector& A)
579  {
580  return (*this = ndBigVector(m_x + A.m_x, m_y + A.m_y, m_z + A.m_z, m_w + A.m_w));
581  }
582 
583  inline ndBigVector& operator-= (const ndBigVector& A)
584  {
585  return (*this = ndBigVector(m_x - A.m_x, m_y - A.m_y, m_z - A.m_z, m_w - A.m_w));
586  }
587 
588  inline ndBigVector& operator*= (const ndBigVector& A)
589  {
590  return (*this = ndBigVector(m_x * A.m_x, m_y * A.m_y, m_z * A.m_z, m_w * A.m_w));
591  }
592 
593  inline ndBigVector MulAdd(const ndBigVector& A, const ndBigVector& B) const
594  {
595  return *this + A * B;
596  }
597 
598  inline ndBigVector MulSub(const ndVector& A, const ndBigVector& B) const
599  {
600  return *this - A * B;
601  }
602 
603 
604  inline ndBigVector AddHorizontal() const
605  {
606  return ndBigVector(m_x + m_y + m_z + m_w);
607  }
608 
609  inline ndBigVector Scale(ndFloat64 scale) const
610  {
611  return ndBigVector(m_x * scale, m_y * scale, m_z * scale, m_w * scale);
612  }
613 
614  // return cross product
615  inline ndBigVector CrossProduct(const ndBigVector& B) const
616  {
617  return ndBigVector(m_y * B.m_z - m_z * B.m_y, m_z * B.m_x - m_x * B.m_z, m_x * B.m_y - m_y * B.m_x, m_w);
618  }
619 
620  inline ndBigVector CrossProduct(const ndBigVector& A, const ndBigVector& B) const
621  {
622  ndFloat64 cofactor[3][3];
623  ndFloat64 array[4][4];
624 
625  const ndBigVector& me = *this;
626  for (ndInt32 i = 0; i < 4; ++i) {
627  array[0][i] = me[i];
628  array[1][i] = A[i];
629  array[2][i] = B[i];
630  array[3][i] = ndFloat32(1.0f);
631  }
632 
633  ndBigVector normal;
634  ndFloat64 sign = ndFloat64(-1.0f);
635  for (ndInt32 i = 0; i < 4; ++i)
636  {
637  for (ndInt32 j = 0; j < 3; ++j)
638  {
639  ndInt32 k0 = 0;
640  for (ndInt32 k = 0; k < 4; ++k)
641  {
642  if (k != i)
643  {
644  cofactor[j][k0] = array[j][k];
645  k0++;
646  }
647  }
648  }
649  ndFloat64 x = cofactor[0][0] * (cofactor[1][1] * cofactor[2][2] - cofactor[1][2] * cofactor[2][1]);
650  ndFloat64 y = cofactor[0][1] * (cofactor[1][2] * cofactor[2][0] - cofactor[1][0] * cofactor[2][2]);
651  ndFloat64 z = cofactor[0][2] * (cofactor[1][0] * cofactor[2][1] - cofactor[1][1] * cofactor[2][0]);
652  ndFloat64 det = x + y + z;
653 
654  normal[i] = sign * det;
655  sign *= ndFloat64(-1.0f);
656  }
657 
658  return normal;
659  }
660 
661  inline ndBigVector GetInt() const
662  {
663  return ndBigVector(ndInt64(floor(m_x)), ndInt64(floor(m_y)), ndInt64(floor(m_z)), ndInt64(floor(m_w)));
664  }
665 
666  inline ndBigVector TestZero() const
667  {
668  const ndInt64* const a = (ndInt64*)&m_x;
669  return ndBigVector((a[0] == 0) ? ndFloat64(-1.0f) : ndFloat64(1.0f),
670  (a[1] == 0) ? ndFloat64(-1.0f) : ndFloat64(1.0f),
671  (a[2] == 0) ? ndFloat64(-1.0f) : ndFloat64(1.0f),
672  (a[3] == 0) ? ndFloat64(-1.0f) : ndFloat64(1.0f));
673  }
674 
675 
676  inline ndBigVector Floor() const
677  {
678  return ndBigVector(floor(m_x), floor(m_y), floor(m_z), floor(m_w));
679  }
680 
681  inline ndBigVector DotProduct(const ndBigVector &A) const
682  {
683  //return ndBigVector(m_x * A.m_x + m_y * A.m_y + m_z * A.m_z + m_w * A.m_w);
684  return (*this * A).AddHorizontal();
685  }
686 
687  inline ndBigVector Reciproc() const
688  {
689  return ndBigVector(ndFloat64(1.0f) / m_x, ndFloat64(1.0f) / m_y, ndFloat64(1.0f) / m_z, ndFloat64(1.0f) / m_w);
690  }
691 
692  inline ndBigVector Sqrt() const
693  {
694  return ndBigVector(sqrt(m_x), sqrt(m_y), sqrt(m_z), sqrt(m_w));
695  }
696 
697  inline ndBigVector InvSqrt() const
698  {
699  return ndBigVector(ndFloat64(1.0f) / sqrt(m_x), ndFloat64(1.0f) / sqrt(m_y), ndFloat64(1.0f) / sqrt(m_z), ndFloat64(1.0f) / sqrt(m_w));
700  }
701 
702  inline ndBigVector InvMagSqrt() const
703  {
704  return ndBigVector(ndFloat64(1.0f) / sqrt(DotProduct(*this).m_x));
705  }
706 
707  inline ndBigVector Normalize() const
708  {
709  return *this * InvMagSqrt();
710  }
711 
712  inline ndBigVector Abs() const
713  {
714  return ndBigVector(
715  (m_x > ndFloat64(0.0f)) ? m_x : -m_x,
716  (m_y > ndFloat64(0.0f)) ? m_y : -m_y,
717  (m_z > ndFloat64(0.0f)) ? m_z : -m_z,
718  (m_w > ndFloat64(0.0f)) ? m_w : -m_w);
719  }
720 
721  inline ndBigVector GetMax() const
722  {
723  return ndBigVector(ndMax(ndMax(m_x, m_y), ndMax(m_z, m_w)));
724  }
725 
726  inline ndBigVector GetMax(const ndBigVector& data) const
727  {
728  return ndBigVector(
729  (m_x > data.m_x) ? m_x : data.m_x,
730  (m_y > data.m_y) ? m_y : data.m_y,
731  (m_z > data.m_z) ? m_z : data.m_z,
732  (m_w > data.m_w) ? m_w : data.m_w);
733  }
734 
735  inline ndBigVector GetMin(const ndBigVector& data) const
736  {
737  return ndBigVector(
738  (m_x < data.m_x) ? m_x : data.m_x,
739  (m_y < data.m_y) ? m_y : data.m_y,
740  (m_z < data.m_z) ? m_z : data.m_z,
741  (m_w < data.m_w) ? m_w : data.m_w);
742  }
743 
744  // relational operators
745  inline ndBigVector operator== (const ndBigVector& data) const
746  {
747  return ndBigVector(
748  (m_x == data.m_x) ? ndInt64(-1) : ndInt64(0),
749  (m_y == data.m_y) ? ndInt64(-1) : ndInt64(0),
750  (m_z == data.m_z) ? ndInt64(-1) : ndInt64(0),
751  (m_w == data.m_w) ? ndInt64(-1) : ndInt64(0));
752  }
753 
754  inline ndBigVector operator> (const ndBigVector& data) const
755  {
756  return ndBigVector(
757  (m_x > data.m_x) ? ndInt64(-1) : ndInt64(0),
758  (m_y > data.m_y) ? ndInt64(-1) : ndInt64(0),
759  (m_z > data.m_z) ? ndInt64(-1) : ndInt64(0),
760  (m_w > data.m_w) ? ndInt64(-1) : ndInt64(0));
761  }
762 
763  inline ndBigVector operator< (const ndBigVector& data) const
764  {
765  return ndBigVector(
766  (m_x < data.m_x) ? ndInt64(-1) : ndInt64(0),
767  (m_y < data.m_y) ? ndInt64(-1) : ndInt64(0),
768  (m_z < data.m_z) ? ndInt64(-1) : ndInt64(0),
769  (m_w < data.m_w) ? ndInt64(-1) : ndInt64(0));
770  }
771 
772  inline ndBigVector operator>= (const ndBigVector& data) const
773  {
774  return ndBigVector(
775  (m_x >= data.m_x) ? ndInt64(-1) : ndInt64(0),
776  (m_y >= data.m_y) ? ndInt64(-1) : ndInt64(0),
777  (m_z >= data.m_z) ? ndInt64(-1) : ndInt64(0),
778  (m_w >= data.m_w) ? ndInt64(-1) : ndInt64(0));
779  }
780 
781  inline ndBigVector operator<= (const ndBigVector& data) const
782  {
783  return ndBigVector(
784  (m_x <= data.m_x) ? ndInt64(-1) : ndInt64(0),
785  (m_y <= data.m_y) ? ndInt64(-1) : ndInt64(0),
786  (m_z <= data.m_z) ? ndInt64(-1) : ndInt64(0),
787  (m_w <= data.m_w) ? ndInt64(-1) : ndInt64(0));
788  }
789 
790  // logical operations
791  inline ndBigVector operator& (const ndBigVector& data) const
792  {
793  const ndInt64* const a = (ndInt64*)&m_x;
794  const ndInt64* const b = (ndInt64*)&data.m_x;
795  return ndBigVector(a[0] & b[0], a[1] & b[1], a[2] & b[2], a[3] & b[3]);
796  }
797 
798  inline ndBigVector operator| (const ndBigVector& data) const
799  {
800  const ndInt64* const a = (ndInt64*)&m_x;
801  const ndInt64* const b = (ndInt64*)&data.m_x;
802  return ndBigVector(a[0] | b[0], a[1] | b[1], a[2] | b[2], a[3] | b[3]);
803  }
804 
805  inline ndBigVector operator^ (const ndBigVector& data) const
806  {
807  const ndInt64* const a = (ndInt64*)&m_x;
808  const ndInt64* const b = (ndInt64*)&data.m_x;
809  return ndBigVector(a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]);
810  }
811 
812  inline ndBigVector AndNot(const ndBigVector& data) const
813  {
814  const ndInt64* const a = (ndInt64*)&m_x;
815  const ndInt64* const b = (ndInt64*)&data.m_x;
816  return ndBigVector(a[0] & ~b[0], a[1] & ~b[1], a[2] & ~b[2], a[3] & ~b[3]);
817  }
818 
819  inline ndBigVector Select(const ndBigVector& data, const ndBigVector& mask) const
820  {
821  // (((b ^ a) & mask)^a)
822  return (*this) ^ (mask & (data ^ (*this)));
823  }
824 
825  inline ndInt32 GetSignMask() const
826  {
827  const ndInt64* const a = (ndInt64*)&m_x;
828  return (((a[0] >> 63) ? 1 : 0) | ((a[1] >> 63) ? 2 : 0) | ((a[2] >> 63) ? 4 : 0) | ((a[3] >> 63) ? 8 : 0));
829  }
830 
831  inline ndVector ShiftRight() const
832  {
833  return ndBigVector(m_w, m_x, m_y, m_z);
834  }
835 
836  inline ndBigVector ShiftTripleRight() const
837  {
838  return ndBigVector(m_z, m_x, m_y, m_w);
839  }
840 
841  inline ndBigVector ShiftTripleLeft() const
842  {
843  return ndBigVector(m_y, m_z, m_x, m_w);
844  }
845 
846  inline ndBigVector ShiftRightLogical(ndInt32 bits) const
847  {
848  return ndBigVector(ndInt64(ndUnsigned64(m_ix) >> bits), ndInt64(ndUnsigned64(m_iy) >> bits), ndInt64(ndUnsigned64(m_iz) >> bits), ndInt64(ndUnsigned64(m_iw) >> bits));
849  }
850 
851  inline static void Transpose4x4(ndBigVector& dst0, ndBigVector& dst1, ndBigVector& dst2, ndBigVector& dst3, const ndBigVector& src0, const ndBigVector& src1, const ndBigVector& src2, const ndBigVector& src3)
852  {
853  ndBigVector tmp0(src0);
854  ndBigVector tmp1(src1);
855  ndBigVector tmp2(src2);
856  ndBigVector tmp3(src3);
857 
858  dst0 = ndBigVector(tmp0.m_x, tmp1.m_x, tmp2.m_x, tmp3.m_x);
859  dst1 = ndBigVector(tmp0.m_y, tmp1.m_y, tmp2.m_y, tmp3.m_y);
860  dst2 = ndBigVector(tmp0.m_z, tmp1.m_z, tmp2.m_z, tmp3.m_z);
861  dst3 = ndBigVector(tmp0.m_w, tmp1.m_w, tmp2.m_w, tmp3.m_w);
862  }
863 
864  union
865  {
866  struct
867  {
868  ndFloat64 m_x;
869  ndFloat64 m_y;
870  ndFloat64 m_z;
871  ndFloat64 m_w;
872  };
873  struct
874  {
875  ndInt64 m_ix;
876  ndInt64 m_iy;
877  ndInt64 m_iz;
878  ndInt64 m_iw;
879  };
880  ndInt64 m_i[4];
881  };
882 
883  D_CORE_API static ndBigVector m_zero;
884  D_CORE_API static ndBigVector m_one;
885  D_CORE_API static ndBigVector m_wOne;
886  D_CORE_API static ndBigVector m_half;
887  D_CORE_API static ndBigVector m_two;
888  D_CORE_API static ndBigVector m_three;
889  D_CORE_API static ndBigVector m_negOne;
890  D_CORE_API static ndBigVector m_xMask;
891  D_CORE_API static ndBigVector m_yMask;
892  D_CORE_API static ndBigVector m_zMask;
893  D_CORE_API static ndBigVector m_wMask;
894  D_CORE_API static ndBigVector m_xyzwMask;
895  D_CORE_API static ndBigVector m_epsilon;
896  D_CORE_API static ndBigVector m_signMask;
897  D_CORE_API static ndBigVector m_triplexMask;
898 } D_GCC_NEWTON_ALIGN_32;
899 
900 #endif
901 #endif
ndBigVector
Definition: ndVectorArmNeon.h:463
ndVector
Definition: ndVectorArmNeon.h:41