diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h')
| -rw-r--r-- | APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h b/APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h new file mode 100644 index 00000000..6f0f9ccf --- /dev/null +++ b/APEX_1.4/shared/internal/include/authoring/ApexCSGFastMath2.h @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + +#ifndef APEX_CSG_FAST_MATH_2_H +#define APEX_CSG_FAST_MATH_2_H + +#include "ApexUsingNamespace.h" +#include "PxMath.h" +#include "PxVec3.h" + +#include "PsUtilities.h" + +#include "PxIntrinsics.h" +#include <emmintrin.h> +#include <fvec.h> + +#include <math.h> +#include <float.h> + +#ifdef __SSE2__ +#define APEX_CSG_SSE +#include <mmintrin.h> +#include <emmintrin.h> +#endif +#ifdef __SSE3__ +#include <pmmintrin.h> +#endif +#ifdef __SSE4_1__ +#include <smmintrin.h> +#endif + +namespace ApexCSG +{ + +/* Utilities */ + +template<typename T> +T square(T t) +{ + return t * t; +} + + +/* Linear algebra */ + +#define ALL_i( _D, _exp ) for( int i = 0; i < _D; ++i ) { _exp; } + +#ifndef APEX_CSG_LOOP_UNROLL +#define APEX_CSG_LOOP_UNROLL 1 +#endif + +#ifndef APEX_CSG_SSE +#define APEX_CSG_SSE 1 +#endif + +#ifndef APEX_CSG_INLINE +#define APEX_CSG_INLINE 1 +#endif + +#ifndef APEX_CSG_ALIGN +#define APEX_CSG_ALIGN 16 +#endif + +#if APEX_CSG_LOOP_UNROLL + +#define VEC_SIZE() sizeof(*this)/sizeof(Real) + +#define OP_VV(a,op,b,i) a[i] op b[i] +#define OP_SV(a,op,b,i) a op b[i] +#define OP_VS(a,op,b,i) a[i] op b +#define OP_VVV(a,op1,b,op2,c,i) a[i] op1 b[i] op2 c[i] +#define OP_SVV(a,op1,b,op2,c,i) a op1 b[i] op2 c[i] +#define OP_VVS(a,op1,b,op2,c,i) a[i] op1 b[i] op2 c +#define OP_D(_D) (_D == 0 ? 0 : (_D == 1 ? 1 : (_D == 2 ? 2 : (_D == 3 ? 3 : 3)))) +#define OP_NAME(_T) PX_CONCAT(OP_,_T) +#define OP_2_NAME(_D) ALL_2_##_D /*PX_CONCAT(ALL_2_,OP_D(_D))*/ +#define OP_3_NAME(_D) ALL_3_##_D /*PX_CONCAT(ALL_3_,OP_D(_D))*/ + +#define ALL_2_1( _T, a,op,b) OP_##_T (a,op,b,0) +#define ALL_2_2( _T, a,op,b) ALL_2_1(_T,a,op,b); OP_##_T (a,op,b,1) +#define ALL_2_3( _T, a,op,b) ALL_2_2(_T,a,op,b); OP_##_T (a,op,b,2) +#define ALL_2_4( _T, a,op,b) ALL_2_3(_T,a,op,b); OP_##_T (a,op,b,3) +#define ALL_VV_i( _D, a,op,b) OP_2_NAME(_D)(VV,a,op,b) +#define ALL_SV_i( _D, a,op,b) OP_2_NAME(_D)(SV,a,op,b) +#define ALL_VS_i( _D, a,op,b) OP_2_NAME(_D)(VS,a,op,b) + +#define ALL_3_1( _T, a,op1,b,op2,c) OP_NAME(_T) (a,op1,b,op2,c,0) +#define ALL_3_2( _T, a,op1,b,op2,c) ALL_3_1(_T,a,op1,b,op2,c); OP_NAME(_T) (a,op1,b,op2,c,1) +#define ALL_3_3( _T, a,op1,b,op2,c) ALL_3_2(_T,a,op1,b,op2,c); OP_NAME(_T) (a,op1,b,op2,c,2) +#define ALL_3_4( _T, a,op1,b,op2,c) ALL_3_3(_T,a,op1,b,op2,c); OP_NAME(_T) (a,op1,b,op2,c,3) +#define ALL_VVV_i( _D, a,op1,b,op2,c) OP_3_NAME(_D)(VVV,a,op1,b,op2,c) +#define ALL_SVV_i( _D, a,op1,b,op2,c) OP_3_NAME(_D)(SVV,a,op1,b,op2,c) +#define ALL_VVS_i( _D, a,op1,b,op2,c) OP_3_NAME(_D)(VVS,a,op1,b,op2,c) +#define ALL_VVV( a,op1,b,op2,c) OP_3_NAME(VEC_SIZE())(VVV,a,op1,b,op2,c) +#define ALL_SVV( a,op1,b,op2,c) OP_3_NAME(VEC_SIZE())(SVV,a,op1,b,op2,c) +#define ALL_VVS( a,op1,b,op2,c) OP_3_NAME(VEC_SIZE())(VVS,a,op1,b,op2,c) + +#else + +#define ALL_VV_i( _D, a,op,b) ALL_i( _D, a[i] op b[i] ) +#define ALL_SV_i( _D, a,op,b) ALL_i( _D, a op b[i] ) +#define ALL_VS_i( _D, a,op,b) ALL_i( _D, a[i] op b ) +#define ALL_VVV_i( _D, a,op1,b,op2,c) ALL_i( _D, a[i] op1 b[i] op2 c[i] ) +#define ALL_SVV_i( _D, a,op1,b,op2,c) ALL_i( _D, a op1 b[i] op2 c[i] ) +#define ALL_VVS_i( _D, a,op1,b,op2,c) ALL_i( _D, a[i] op1 b[i] op2 c ) + +#endif + +#if 1 + +#define DEFINE_VEC(_D) \ + public: \ + typedef Vec<T,_D> VecD; \ + PX_INLINE VecD() {} \ + PX_INLINE T& operator [](int i) { return el[i]; } \ + PX_INLINE const T& operator [](int i) const { return el[i]; } \ + PX_INLINE VecD(const VecD& v) { set(v); } \ + PX_INLINE VecD(const T& v) { set(v); } \ + PX_INLINE VecD(const T* v) { set(v); } \ + PX_INLINE VecD& operator=(const VecD& v) { ALL_VV_i(_D, el, =, v); return *this; } \ + PX_INLINE VecD operator/(T v) const { return *this * ((T)1 / v); } \ + PX_INLINE VecD operator+(const VecD& v) const { VecD r; ALL_VVV_i(_D, r, =, el, +, v); return r; } \ + PX_INLINE VecD operator-(const VecD& v) const { VecD r; ALL_VVV_i(_D, r, =, el, -, v); return r; } \ + PX_INLINE VecD operator*(const VecD& v) const { VecD r; ALL_VVV_i(_D, r, =, el, *, v); return r; } \ + PX_INLINE VecD operator-( ) const { VecD r; ALL_VV_i( _D, r, =, -el); return r;} \ + PX_INLINE VecD& operator+=(const VecD& v) {ALL_VV_i(_D, el, +=, v); return *this; } \ + PX_INLINE VecD& operator-=(const VecD& v) {ALL_VV_i(_D, el, -=, v); return *this; } \ + PX_INLINE VecD& operator*=(const VecD& v) {ALL_VV_i(_D, el, *=, v); return *this; } \ + PX_INLINE VecD& operator/=(const VecD& v) {ALL_VV_i(_D, el, /=, v); return *this; } \ + PX_INLINE void set(const VecD& v) { ALL_VV_i(_D, el, =, v); } \ + PX_INLINE void set(const T* v) { ALL_VV_i(_D, el, =, v); } \ + PX_INLINE void set(const T& v) { ALL_VS_i(_D, el, =, v); } \ + PX_INLINE T lengthSquared() const { return *this | *this; } \ + PX_INLINE T normalize() { const T l2 = *this | *this; if (l2 == (T)0) { return (T)0; } const T recipL = (T)1 / physx::PxSqrt(l2); *this *= recipL; return recipL * l2; } \ + protected:T el[_D]; \ + + //PX_FORCE_INLINE T operator|(const VecD& v) const { T r = (T)0; ALL_SVV_i(_D, r, +=, el, *, v); return r; } +#endif + +/* General vector */ + +__declspec(align(APEX_CSG_ALIGN)) class aligned { }; + +template<typename T, int D> +class Vec : public aligned +{ + +}; + + +template<typename T, int D> +PX_INLINE Vec<T, D> +operator * (T s, const Vec<T, D>& v) +{ + Vec<T, D> r; + ALL_i(D, r[i] = s * v[i]); + //ALL_VVS_i(D, r, =, v, *, s); + return r; +} + +template<typename T> +class Vec<T, 2> : public aligned { + DEFINE_VEC(2); +public: + typedef Vec<T,2> Vec2; + + PX_INLINE Vec2(T x, T y) + { + set(x, y); + } + + PX_INLINE void set(T x, T y) + { + el[0] = x; + el[1] = y; + } + + PX_INLINE Real operator ^ (const Vec2& v) const + { + return el[0] * v.el[1] - el[1] * v.el[0]; + } + + PX_FORCE_INLINE T operator | (const Vec2& v) const + { + T r = (T)0; + ALL_SVV_i(2, r, +=, el, *, v); + return r; + } + +}; + +template<typename T> +class Vec<T, 3> : public aligned { + DEFINE_VEC(3); +public: + typedef Vec<T,3> Vec3; + + PX_INLINE Vec3(T x, T y, T z) + { + set(x, y, z); + } + + PX_INLINE void set(T x, T y, T z) + { + el[0] = x; + el[1] = y; + el[2] = z; + } + + PX_FORCE_INLINE T operator | (const Vec3& v) const + { + T r = (T)0; + ALL_SVV_i(3, r, +=, el, *, v); + return r; + } +}; + +template<typename T> +class Vec<T, 4> : public aligned { + DEFINE_VEC(4); +public: + typedef Vec<T,4> Vec4; + + PX_INLINE Vec4(T x, T y, T z, T w) + { + set(x, y, z, w); + } + + PX_INLINE void set(T x, T y, T z, T w) + { + el[0] = x; + el[1] = y; + el[2] = z; + el[3] = w; + } + +#if APEX_CSG_SSE + +#if APEX_CSG_DBL + PX_INLINE __m128d& xy() { return *reinterpret_cast< __m128d*>(&el[0]); } + PX_INLINE const __m128d& xy() const { return *reinterpret_cast<const __m128d*>(&el[0]); } + PX_INLINE __m128d& zw() { return *reinterpret_cast< __m128d*>(&el[2]); } + PX_INLINE const __m128d& zw() const { return *reinterpret_cast<const __m128d*>(&el[2]); } +#else + PX_INLINE __m128& xyzw() { return *reinterpret_cast< __m128*>(&el[0]); } + PX_INLINE const __m128& xyzw() const { return *reinterpret_cast<const __m128*>(&el[0]); } +#endif /* #if APEX_CSG_DBL */ + + friend Real dot(const Vec4&, const Vec4&); + PX_FORCE_INLINE Real operator | (const Vec4& v) const + { + return dot(*this, v); + } + +#endif /* #if APEX_CSG_SSE */ +}; + +/* Popular real vectors */ + +typedef Vec<Real, 2> Vec2Real; +typedef Vec<Real, 3> Vec3Real; +typedef Vec<Real, 4> Vec4Real; + +#if APEX_CSG_SSE + +#if APEX_CSG_DBL + +PX_FORCE_INLINE Real dot(const Vec4Real& a, const Vec4Real& b) +{ + /* + __m128d mr = _mm_add_sd ( _mm_mul_pd ( a.xy(), b.xy()), + _mm_mul_sd ( a.zw(), b.zw()) ) ; + mr = _mm_add_sd ( _mm_unpackhi_pd ( mr , mr ), mr ); + double r; + _mm_store_sd(&r, mr); + return r;*/ + __declspec(align(16)) double r[2] = { 0., 0. }; + __m128d mresult; + mresult = _mm_add_pd(_mm_mul_pd( a.xy(), b.xy() ), + _mm_mul_pd( a.zw(), b.zw() ) ); + _mm_store_pd(r, mresult); + return r[0] + r[1]; +} + +#else + +PX_FORCE_INLINE Real dot(const Vec4Real& a, const Vec4Real& b) +{ + float r; + _mm_store_ps(&s, _mm_dot_pos(a.xyzw(), b.xyzw())); + return r; +} + +#endif /* #if APEX_CSG_DBL */ + +#else + +PX_FORCE_INLINE Real dot(const Vec4Real& a, const Vec4Real& b) +{ + Real r = 0; + ALL_SVV_i(sizeof(a)/sizeof(Real), r, +=, a, *, b); + return r; +} + +#endif /* #if APEX_CSG_SSE */ + +/* Position */ + +class Pos : public Vec4Real +{ +public: + + PX_INLINE Pos() + { + el[3] = 1; + } + PX_INLINE Pos(Real x, Real y, Real z) + { + set(x, y, z); + } + PX_INLINE Pos(Real c) + { + set(c, c, c); + } + PX_INLINE Pos(physx::PxVec3 p) + { + set(p.x, p.y, p.z); + } + PX_INLINE Pos(const Vec<Real, 4>& v) + { + set(v[0], v[1], v[2]); + } + PX_INLINE Pos(const float* v) + { + set((Real)v[0], (Real)v[1], (Real)v[2]); + } + PX_INLINE Pos(const double* v) + { + set((Real)v[0], (Real)v[1], (Real)v[2]); + } + PX_INLINE Pos(const Pos& p) + { + set(p[0], p[1], p[2]); + } + PX_INLINE Pos& operator = (const Pos& p) + { + set(p[0], p[1], p[2]); + return *this; + } + + PX_INLINE void set(Real x, Real y, Real z) + { + Vec4Real::set(x, y, z, (Real)1); + } + +}; + + +/* Direction */ + +class Dir : public Vec4Real +{ +public: + + PX_INLINE Dir() + { + el[3] = 0; + } + PX_INLINE Dir(Real x, Real y, Real z) + { + set(x, y, z); + } + PX_INLINE Dir(Real c) + { + set(c, c, c); + } + PX_INLINE Dir(physx::PxVec3 p) + { + set(p.x, p.y, p.z); + } + PX_INLINE Dir(const Vec<Real, 4>& v) + { + set(v[0], v[1], v[2]); + } + PX_INLINE Dir(const float* v) + { + set((Real)v[0], (Real)v[1], (Real)v[2]); + } + PX_INLINE Dir(const double* v) + { + set((Real)v[0], (Real)v[1], (Real)v[2]); + } + PX_INLINE Dir(const Dir& d) + { + set(d[0], d[1], d[2]); + } + PX_INLINE Dir& operator = (const Dir& d) + { + set(d[0], d[1], d[2]); + return *this; + } + + PX_INLINE void set(Real x, Real y, Real z) + { + Vec4Real::set(x, y, z, (Real)0); + } + + PX_INLINE Dir operator ^(const Dir& d) const + { + return Dir(el[1] * d[2] - el[2] * d[1], el[2] * d[0] - el[0] * d[2], el[0] * d[1] - el[1] * d[0]); + } + +}; + + +/* Plane */ + +class Plane : public Vec4Real +{ +public: + + PX_INLINE Plane() {} + PX_INLINE Plane(const Dir& n, Real d) + { + set(n, d); + } + PX_INLINE Plane(const Dir& n, const Pos& p) + { + set(n, p); + } + PX_INLINE Plane(const Vec<Real, 4>& v) + { + Vec4Real::set(v[0], v[1], v[2], v[3]); + } + PX_INLINE Plane(const Plane& p) + { + //ALL_i(4, el[i] = p[i]); + ALL_VV_i(4, el, =, p); + } + PX_INLINE Plane& operator = (const Plane& p) + { + ALL_VV_i(4, el, =, p); + //ALL_i(4, el[i] = p[i]); + return *this; + } + + PX_INLINE void set(const Dir& n, Real d) + { + //ALL_i(3, el[i] = n[i]); + ALL_VV_i(3, el, =, n); + el[3] = d; + } + PX_INLINE void set(const Dir& n, const Pos& p) + { + //ALL_i(3, el[i] = n[i]); + ALL_VV_i(3, el, =, n); + el[3] = -(n | p); + } + + PX_INLINE Dir normal() const + { + return Dir(el[0], el[1], el[2]); + } + PX_INLINE Real d() const + { + return el[3]; + } + PX_INLINE Real distance(const Pos& p) const + { + return p | *this; + } + PX_INLINE Pos project(const Pos& p) const + { + return p - normal() * distance(p); + } + + PX_INLINE Real normalize(); +}; + +PX_INLINE Real +Plane::normalize() +{ + const Real oldD = el[3]; + el[3] = 0; + const Real l2 = *this | *this; + if (l2 == 0) + { + return 0; + } + const Real recipL = 1. / physx::PxSqrt(l2); + el[3] = oldD; + *this *= recipL; + return recipL * l2; +} + + +/* Matrix */ + +__declspec(align(16)) class Mat4Real : public Vec<Vec4Real, 4> +{ +public: + + PX_INLINE Mat4Real() {} + PX_INLINE Mat4Real(const Real v) + { + set(v); + } + PX_INLINE Mat4Real(const Real* v) + { + set(v); + } + + PX_INLINE void set(const Real v) + { + el[0].set(v, 0, 0, 0); + el[1].set(0, v, 0, 0); + el[2].set(0, 0, v, 0); + el[3].set(0, 0, 0, v); + } + PX_INLINE void set(const Real* v) + { + ALL_i(4, el[i].set(v + 4 * i)); + } + PX_INLINE void setCol(int colN, const Vec4Real& col) + { + ALL_i(4, el[i][colN] = col[i]); + } + + PX_INLINE Vec4Real operator * (const Vec4Real& v) const + { + Vec4Real r; + //ALL_i(4, r[i] = el[i] | v); + ALL_VVS_i(4, r, =, el, |, v); + return r; + } + PX_INLINE Mat4Real operator * (const Mat4Real& m) const + { + Mat4Real r((Real)0); + for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) for (int k = 0; k < 4; ++k) + { + r[i][j] += el[i][k] * m[k][j]; + } + return r; + } + PX_INLINE Mat4Real operator * (Real s) const + { + Mat4Real r; + //ALL_i(4, r[i] = el[i] * s); + ALL_VVS_i(4, r, =, el, *, s); + return r; + } + PX_INLINE Mat4Real operator / (Real s) const + { + return *this * ((Real)1 / s); + } + + PX_INLINE Mat4Real& operator *= (Real s) + { + //ALL_i(4, el[i] *= s); + ALL_VS_i(4, el, *=, s); + return *this; + } + PX_INLINE Mat4Real& operator /= (Real s) + { + *this *= ((Real)1 / s); + return *this; + } + + PX_INLINE Vec4Real getCol(int colN) const + { + Vec4Real col; + ALL_i(4, col[i] = el[i][colN]); + return col; + } + PX_INLINE Real det3() const + { + return el[0] | (Dir(el[1]) ^ Dir(el[2])); // Determinant of upper-left 3x3 block (same as full determinant if last row = (0,0,0,1)) + } + PX_INLINE Mat4Real cof34() const; // Assumes last row = (0,0,0,1) + PX_INLINE Mat4Real inverse34() const; // Assumes last row = (0,0,0,1) +}; + +PX_INLINE Mat4Real +Mat4Real::cof34() const +{ + Mat4Real r; + r[0].set(el[1][1]*el[2][2] - el[1][2]*el[2][1], el[1][2]*el[2][0] - el[1][0]*el[2][2], el[1][0]*el[2][1] - el[1][1]*el[2][0], 0); + r[1].set(el[2][1]*el[0][2] - el[2][2]*el[0][1], el[2][2]*el[0][0] - el[2][0]*el[0][2], el[2][0]*el[0][1] - el[2][1]*el[0][0], 0); + r[2].set(el[0][1]*el[1][2] - el[0][2]*el[1][1], el[0][2]*el[1][0] - el[0][0]*el[1][2], el[0][0]*el[1][1] - el[0][1]*el[1][0], 0); + r[3] = -el[0][3] * r[0] - el[1][3] * r[1] - el[2][3] * r[2]; + r[3][3] = r[0][0] * el[0][0] + r[0][1] * el[0][1] + r[0][2] * el[0][2]; + return r; +} + +PX_INLINE Mat4Real +Mat4Real::inverse34() const +{ + const Mat4Real cof = cof34(); + Mat4Real inv; + const Real recipDet = physx::PxAbs(cof[3][3]) > EPS_REAL * EPS_REAL * EPS_REAL ? 1 / cof[3][3] : (Real)0; + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 4; ++j) + { + inv[i][j] = cof[j][i] * recipDet; + } + } + inv[3].set(0, 0, 0, 1); + return inv; +} + +PX_INLINE Mat4Real +operator * (Real s, const Mat4Real& m) +{ + Mat4Real r; + //ALL_i(4, r[i] = s * m[i]); + ALL_VVS_i(4, r, =, m, *, s); + return r; +} + +} // namespace ApexCSG + +#endif // #define APEX_CSG_FAST_MATH_2_H |