// // Big Vector and Sparse Matrix Classes // // (c) S Melax 2006 // // The focus is on 3D applications, so // the big vector is an array of float3s // and the matrix class uses 3x3 blocks. // // This file includes both: // - basic non-optimized version // - an expression optimized version // // Optimized Expressions // // We want to write sweet looking code such as V=As+Bt with big vectors. // However, we dont want the extra overheads with allocating memory for temps and excessing copying. // Instead of a full Template Metaprogramming approach, we explicitly write // classes to specifically handle all the expressions we are likely to use. // Most applicable lines of code will be of the same handful of basic forms, // but with different parameters for the operands. // In the future, if we ever need a longer expression with more operands, // then we will just add whatever additional building blocks that are necessary - not a big deal. // This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc) // than template metaprogramming is. We do not rely on the implementation // of a particular compiler to be able to expand extensive nested inline codes. // Additionally, we reliably get our optimizations even within a debug build. // Therefore we believe that our Optimized Expressions // are a good compromise that give us the best of both worlds. // The code within those important algorithms, which use this library, // can now remain clean and readable yet still execute quickly. // #ifndef SM_VEC3N_H #define SM_VEC3N_H #include "vecmath.h" #include "array.h" //#include //template void * vec4::operator new[](size_t n){ return _mm_malloc(n,64); } //template void vec4::operator delete[](void *a) { _mm_free(a); } struct HalfConstraint { float3 n;int vi; float s,t; HalfConstraint(const float3& _n,int _vi,float _t):n(_n),vi(_vi),s(0),t(_t){} HalfConstraint():vi(-1){} }; class float3Nx3N { public: class Block { public: float3x3 m; int r,c; float unused[16]; Block(){} Block(short _r,short _c):r(_r),c(_c){m.x=m.y=m.z=float3(0,0,0);} }; Array blocks; // the first n blocks use as the diagonal. int n; void Zero(); void InitDiagonal(float d); void Identity(){InitDiagonal(1.0f);} float3Nx3N():n(0){} float3Nx3N(int _n):n(_n) {for(int i=0;i float3Nx3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} template float3Nx3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} template float3Nx3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;} }; class float3N: public Array { public: float3N(int _count=0) { SetSize(_count); } void Zero(); void Init(const float3 &v); // sets each subvector to v template float3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} template float3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} template float3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;} float3N &operator=( const float3N &V) { this->copy(V); return *this;} }; int ConjGradient(float3N &X, float3Nx3N &A, float3N &B); int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S,Array &H); int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S); inline float3N& Mul(float3N &r,const float3Nx3N &m, const float3N &v) { int i; for(i=0;i