//! \file Kazu.cpp //! @brief fast test for kazu //--------------------------------------------------------------------------- //Boost.asserts #include //Boost.operators #include //SL.Math #include //SL.assert #include //STL.cout #include ////////////////////////////////////////////////////////////////////////// //forward declaration namespace kazu { template struct blast { //vec fwd decl struct vec2; struct vec3; struct vec4; struct vec4D; //mat fwd decl struct mat2x2; struct mat2x3; struct mat2x4; struct mat3x2; struct mat3x3; struct mat3x4; struct mat4x2; struct mat4x3; struct mat4x4; //other fwd decl: complex, hypercomplex struct complex; struct quaternion; struct octonion; //typedefs typedef scalarT scalar; typedef mat2x2 mat2; typedef mat3x3 mat3; typedef mat4x4 mat4; //utility classes template struct vecproto; template struct matproto; }; }//namespace kazu ////////////////////////////////////////////////////////////////////////// //vecproto - template definition namespace kazu { template > struct unary : B { friend selfT sin(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)sin( a._a[i] ); } return rv; } friend selfT cos(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)cps( a._a[i] ); } return rv; } friend selfT tan(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)tan( a._a[i] ); } return rv; } friend selfT asin(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)asin( a._a[i] ); } return rv; } friend selfT acos(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)acos( a._a[i] ); } return rv; } friend selfT atan(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)atan( a._a[i] ); } return rv; } friend selfT exp(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)exp( a._a[i] ); } return rv; } friend selfT log(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)log( a._a[i] ); } return rv; } friend selfT exp2(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)exp2( a._a[i] ); } return rv; } friend selfT log2(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)log2( a._a[i] ); } return rv; } friend selfT sqrt(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)sqrt( a._a[i] ); } return rv; } friend selfT abs(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)abs( a._a[i] ); } return rv; } friend selfT sign(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)sign( a._a[i] ); } return rv; } friend selfT floor(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)floor( a._a[i] ); } return rv; } friend selfT ceil(const selfT& a) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)ceil( a._a[i] ); } return rv; } }; template > struct binary : B { friend selfT pow(const selfT& a, const selfT& b) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)pow( a._a[i], b._a[i] ); } return rv; } friend selfT pow(const selfT& a, const typeT b) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)pow( a._a[i], b ); } return rv; } friend selfT min(const selfT& a, const selfT& b) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)min( a._a[i], b._a[i] ); } return rv; } friend selfT max(const selfT& a, const selfT& b) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)max( a._a[i], b._a[i] ); } return rv; } }; template > struct trinary : B { friend selfT clamp(const selfT& a, const selfT& b, const selfT& c) { selfT rv(a); for(unsigned int i = 0; i < dimT; i++){ rv._a[i] = (typeT)clamp( a._a[i], b._a[i], c._a[i] ); } return rv; } }; } ////////////////////////////////////////////////////////////////////////// //vec member namespace kazu { template struct vecmember; } template struct kazu::vecmember { union { typeT _a[2]; struct { typeT x, y; }; struct { typeT i, a; }; struct { typeT s, t; }; struct { typeT _0, _1; }; }; }; template struct kazu::vecmember { union { typeT _a[3]; struct { typeT x, y, z; }; struct { typeT r, g, b; }; struct { typeT s, t, p; }; struct { typeT _0, _1, _2; }; }; }; template struct kazu::vecmember { union { typeT _a[4]; struct { typeT x, y, z, w; }; struct { typeT r, g, b, a; }; struct { typeT s, t, p, q; }; struct { typeT _0, _1, _2, _3; }; }; }; ////////////////////////////////////////////////////////////////////////// //definition of vec classes template struct kazu::blast::vec2 : public kazu::blast::vecproto { vec2() {} vec2(const vec2& b) { x = b.x; y = b.y; } vec2(const vecproto& b) { x = b.x; y = b.y; } vec2(typeT _x, typeT _y) { x = _x; y = _y; } vec2(const typeT a[2]) { for(unsigned int i = 0; i < 2; i++) { _a[i] = a[i]; } } virtual ~vec2(){} virtual vec2 cross(const vec2& rhv) const { vec2 rv; //not sure, should return 0, 0 rv.x = this->x * rhv.y; rv.y = this->y * rhv.x; return rv; } }; template struct kazu::blast::vec3 : public kazu::blast::vecproto { vec3() {} vec3(const vec3& b) { x = b.x; y = b.y; z = b.z; } vec3(const vecproto& b) { x = b.x; y = b.y; z = b.z; } vec3(typeT _x, typeT _y, typeT _z) { x = _x; y = _y; z = _z; } vec3(const typeT a[3]) { for(unsigned int i = 0; i < 3; i++) { _a[i] = a[i]; } } vec3(const vec2& b, typeT _z = (typeT)0) { x = b.x; y = b.y; z = _z; } vec3(const vec4& b) { x = b.x/b.w; y = b.y/b.w; z = b.z/b.w; } virtual ~vec3(){} virtual vec3 cross(const vec3& rhv) const { vec3 rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; return rv; } }; template struct kazu::blast::vec4 : public kazu::blast::vecproto { vec4() {} vec4(const vec4& b) { x = b.x; y = b.y; z = b.z; w = b.w; } vec4(const vecproto& b) { x = b.x; y = b.y; z = b.z; w = b.w; } vec4(typeT _x, typeT _y, typeT _z, typeT _w) { x = _x; y = _y; z = _z; w = _w; } vec4(const typeT a[4]) { for(unsigned int i = 0; i < 4; i++) { _a[i] = a[i]; } } vec4(const vec2& b, typeT _z = (typeT)0, typeT _w = (typeT)1) { x = b.x; y = b.y; z = _z; w = _w; } vec4(const vec3& b, typeT _w = (typeT)1) { x = b.x; y = b.y; z = b.z; w = _w; } virtual ~vec4(){} virtual vec4 cross(const vec4& rhv) const { vec4 rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; rv.w = this->w * rhv.w; //not sure about this one return rv; } }; template struct kazu::blast::vec4D : kazu::blast::vec4 { virtual vec4D cross(const vec4D& b) const { vec4D rv; //4D cross rv.x = this->y * rhv.z - this->z * rhv.y + this->z * rhv.w - this->w * rhv.z + this->y * rhv.w - this->w * rhv.y; rv.y = this->z * rhv.x - this->x * rhv.z + this->w * rhv.x - this->x * rhv.w + this->z * rhv.w - this->w * rhv.z; rv.z = this->x * rhv.y - this->y * rhv.x + this->w * rhv.y - this->y * rhv.w + this->w * rhv.x - this->x * rhv.w; rv.w = this->x * rhv.y - this->y * rhv.x + this->y * rhv.z - this->z * rhv.y + this->x * rhv.z - this->z * rhv.x; return rv; } }; ////////////////////////////////////////////////////////////////////////// //vec swizzle namespace kazu { template > struct vecaccess : B { inline typeT& operator[](unsigned int idx) { assert(idx < dimT); return this->_a[idx]; } inline const typeT& operator[](unsigned int idx) const { assert(idx < dimT); return this->_a[idx]; } inline operator typeT*() { return &this->_a[0]; } //swizzle template inline typeT& get() { BOOST_STATIC_ASSERT(X < dimT); return this->_a[X]; } template inline const typeT& get() const { BOOST_STATIC_ASSERT(X < dimT); return this->_a[X]; } template inline vecT2 swizzle2() { return vecT2(this->get(), this->get()); } template inline const vecT2 swizzle2() const { return vecT2(this->get(), this->get()); } template inline vecT3 swizzle3() { return vecT3(this->get(), this->get(), this->get()); } template inline const vecT3 swizzle3() const { return vecT3(this->get(), this->get(), this->get()); } template inline vecT4 swizzle4() { return vecT4(this->get(), this->get(), this->get(), this->get()); } template inline const vecT4 swizzle4() const { return vecT4(this->get(), this->get(), this->get(), this->get()); } }; template > struct vecswizzle; } template struct kazu::vecswizzle : B { vecT2 xx() { return this->swizzle2<0, 0>(); } const vecT2 xx() const { return this->swizzle2<0, 0>(); } vecT3 xxx() { return this->swizzle3<0, 0, 0>(); } const vecT3 xxx() const { return this->swizzle3<0, 0, 0>(); } vecT4 xxxx() { return this->swizzle4<0, 0, 0, 0>(); } const vecT4 xxxx() const { return this->swizzle4<0, 0, 0, 0>(); } }; template struct kazu::vecswizzle : kazu::vecswizzle { vecT2 yy() { return this->swizzle2<1, 1>(); } const vecT2 yy() const { return this->swizzle2<1, 1>(); } vecT3 yyy() { return this->swizzle3<1, 1, 1>(); } const vecT3 yyy() const { return this->swizzle3<1, 1, 1>(); } vecT4 yyyy() { return this->swizzle4<1, 1, 1, 1>(); } const vecT4 yyyy() const { return this->swizzle4<1, 1, 1, 1>(); } }; template struct kazu::vecswizzle : kazu::vecswizzle { vecT2 zz() { return this->swizzle2<2, 2>(); } const vecT2 zz() const { return this->swizzle2<2, 2>(); } vecT3 zzz() { return this->swizzle3<2, 2, 2>(); } const vecT3 zzz() const { return this->swizzle3<2, 2, 2>(); } vecT4 zzzz() { return this->swizzle4<2, 2, 2, 2>(); } const vecT4 zzzz() const { return this->swizzle4<2, 2, 2, 2>(); } }; template struct kazu::vecswizzle : kazu::vecswizzle { vecT2 ww() { return this->swizzle2<3, 3>(); } const vecT2 ww() const { return this->swizzle2<3, 3>(); } vecT3 www() { return this->swizzle3<3, 3, 3>(); } const vecT3 www() const { return this->swizzle3<3, 3, 3>(); } vecT4 wwww() { return this->swizzle4<3, 3, 3, 3>(); } const vecT4 wwww() const { return this->swizzle4<3, 3, 3, 3>(); } }; ////////////////////////////////////////////////////////////////////////// template template struct kazu::blast::vecproto : public boost::arithmetic< selfT, boost::multiplicative< selfT, typeT, kazu::unary > > > > > > > { // selfT(typeT a[dimT]) { for (unsigned i = 0; i < dimT; i++){ this->_a[i] = a[i]; } } //sum inline typeT sum() { typeT rv = (typeT)0; for(unsigned int i = 0; i < dimT; i++){rv += this->_a[i];} return rv; } //dot virtual typeT dot(const selfT& b) { selfT rv(*this); rv *= b; return rv.sum(); } inline friend typeT dot(const selfT& a, const selfT& b) { return a.dot(b); } //cross // virtual selfT cross(const selfT& b); //todo: implement in specialization inline friend selfT cross(const selfT& a, const selfT& b) { return a.cross(b); } //length inline typeT lensq() { selfT a(*this); a *= a; return a.sum(); } inline friend typeT lensq(const selfT& a) { return a.lensq(); } inline typeT length() { return std::sqrt( lensq() ); } inline friend typeT length(const selfT& a) { return a.length(); } inline typeT distance(const selfT& rhv) { selfT a = rhv - (*this); return a.length(); } inline friend typeT distance(const selfT& a, const selfT& b) { return a.distance(b); } //normalize inline selfT normalize() { selfT a(*this); return a /= this->length(); } inline friend typeT normalize(const selfT& a) { return a.normalize(); } //operators inline selfT& operator=(const selfT& b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] = b._a[i]; } return *this; } inline selfT& operator+=(const selfT& b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] += b._a[i]; } return *this; } inline selfT& operator-=(const selfT& b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] -= b._a[i]; } return *this; } inline selfT& operator*=(const selfT& b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b._a[i]; } return *(selfT*)(this); } inline selfT& operator/=(const selfT& b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b._a[i]; } return *this; } inline selfT& operator*=(const typeT b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b; } return *this; } inline selfT& operator/=(const typeT b) { for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b; } return *this; } //this ought to crash the compiler, or at least induce errors // selfT& operator+=(const selfT& b) { (*this) = (*this) + b; return *this; } // selfT& operator-=(const selfT& b) { (*this) = (*this) - b; return *this; } // selfT& operator*=(const selfT& b) { (*this) = (*this) * b; return *(selfT*)this; } // selfT& operator/=(const selfT& b) { (*this) = (*this) / b; return *this; } template inline friend std::basic_ostream<_Elem, _Traits>& operator<<(std::basic_ostream<_Elem, _Traits>& os, const selfT& a) { os << "vec" << dimT << " <"; for(unsigned int i = 0; i < dimT; i++) { if(i) os << ", "; os << a[i]; } os << "> "; return os; } }; ////////////////////////////////////////////////////////////////////////// //specialization of cross() /* template template selfT kazu::blast::vecproto::cross(const selfT& rhv) { selfT rv; //not sure, should return 0, 0 rv.x = this->x * rhv.y; rv.y = this->y * rhv.x; return rv; } template template selfT kazu::blast::vecproto::cross(const selfT& rhv) { selfT rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; return rv; } template template selfT kazu::blast::vecproto::cross(const selfT& rhv) { selfT rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; rv.w = this->w * rhv.w; //not sure about this one //4D cross // rv.x = this->y * rhv.z - this->z * rhv.y + this->z * rhv.w - this->w * rhv.z + this->y * rhv.w - this->w * rhv.y; // rv.y = this->z * rhv.x - this->x * rhv.z + this->w * rhv.x - this->x * rhv.w + this->z * rhv.w - this->w * rhv.z; // rv.z = this->x * rhv.y - this->y * rhv.x + this->w * rhv.y - this->y * rhv.w + this->w * rhv.x - this->x * rhv.w; // rv.w = this->x * rhv.y - this->y * rhv.x + this->y * rhv.z - this->z * rhv.y + this->x * rhv.z - this->z * rhv.x; return rv; } */ /* template kazu::blast::vec2 kazu::blast::vec2::cross(const kazu::blast::vec2& rhv) { kazu::blast::vec2 rv; //not sure, should return 0, 0 rv.x = this->x * rhv.y; rv.y = this->y * rhv.x; return rv; } template kazu::blast::vec3 kazu::blast::vec3::cross(const kazu::blast::vec3& rhv) { kazu::blast::vec3 rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; return rv; } template kazu::blast::vec4 kazu::blast::vec4::cross(const kazu::blast::vec4& rhv) { kazu::blast::vec4 rv; rv.x = this->y * rhv.z - this->z * rhv.y; rv.y = this->y * rhv.z - this->z * rhv.y; rv.z = this->y * rhv.z - this->z * rhv.y; rv.w = this->w * rhv.w; //not sure about this one return rv; } template kazu::blast::vec4D kazu::blast::vec4D::cross(const kazu::blast::vec4D& rhv) { kazu::blast::vec4D rv; //4D cross rv.x = this->y * rhv.z - this->z * rhv.y + this->z * rhv.w - this->w * rhv.z + this->y * rhv.w - this->w * rhv.y; rv.y = this->z * rhv.x - this->x * rhv.z + this->w * rhv.x - this->x * rhv.w + this->z * rhv.w - this->w * rhv.z; rv.z = this->x * rhv.y - this->y * rhv.x + this->w * rhv.y - this->y * rhv.w + this->w * rhv.x - this->x * rhv.w; rv.w = this->x * rhv.y - this->y * rhv.x + this->y * rhv.z - this->z * rhv.y + this->x * rhv.z - this->z * rhv.x; return rv; } */ ////////////////////////////////////////////////////////////////////////// //definition of swizzle functions /* template template template inline kazu::blast::vec2 kazu::blast::vecproto::swizzle2() { return kazu::blast::vec2(this->get(), this->get()); } template template template inline const kazu::blast::vec2 kazu::blast::vecproto::swizzle2() const { return kazu::blast::vec2(this->get(), this->get()); } template template template inline kazu::blast::vec3 kazu::blast::vecproto::swizzle3() { return kazu::blast::vec3(this->get(), this->get(), this->get()); } template template template inline const kazu::blast::vec3 kazu::blast::vecproto::swizzle3() const { return kazu::blast::vec3(this->get(), this->get(), this->get()); } template template template inline kazu::blast::vec4 kazu::blast::vecproto::swizzle4() { return kazu::blast::vec4(this->get(), this->get(), this->get(), this->get()); } template template template inline const kazu::blast::vec4 kazu::blast::vecproto::swizzle4() const { return kazu::blast::vec4(this->get(), this->get(), this->get(), this->get()); } */ ////////////////////////////////////////////////////////////////////////// //definition of swizzle functions /* template kazu::blast::vec2 kazu::blast::vec2::xx() { return this->swizzle2<0, 0>(); } template const kazu::blast::vec2 kazu::blast::vec2::xx() const { return this->swizzle2<0, 0>(); } template kazu::blast::vec3 kazu::blast::vec2::xxx() { return this->swizzle3<0, 0, 0>(); } template const kazu::blast::vec3 kazu::blast::vec2::xxx() const { return this->swizzle3<0, 0, 0>(); } template kazu::blast::vec4 kazu::blast::vec2::xxxx() { return this->swizzle4<0, 0, 0, 0>(); } template const kazu::blast::vec4 kazu::blast::vec2::xxxx() const { return this->swizzle4<0, 0, 0, 0>(); } template kazu::blast::vec2 kazu::blast::vec3::xx() { return this->swizzle2<0, 0>(); } template const kazu::blast::vec2 kazu::blast::vec3::xx() const { return this->swizzle2<0, 0>(); } template kazu::blast::vec3 kazu::blast::vec3::xxx() { return this->swizzle3<0, 0, 0>(); } template const kazu::blast::vec3 kazu::blast::vec3::xxx() const { return this->swizzle3<0, 0, 0>(); } template kazu::blast::vec4 kazu::blast::vec3::xxxx() { return this->swizzle4<0, 0, 0, 0>(); } template const kazu::blast::vec4 kazu::blast::vec3::xxxx() const { return this->swizzle4<0, 0, 0, 0>(); } template kazu::blast::vec2 kazu::blast::vec4::xx() { return this->swizzle2<0, 0>(); } template const kazu::blast::vec2 kazu::blast::vec4::xx() const { return this->swizzle2<0, 0>(); } template kazu::blast::vec3 kazu::blast::vec4::xxx() { return this->swizzle3<0, 0, 0>(); } template const kazu::blast::vec3 kazu::blast::vec4::xxx() const { return this->swizzle3<0, 0, 0>(); } template kazu::blast::vec4 kazu::blast::vec4::xxxx() { return this->swizzle4<0, 0, 0, 0>(); } template const kazu::blast::vec4 kazu::blast::vec4::xxxx()const { return this->swizzle4<0, 0, 0, 0>(); } */ ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { kazu::blast::vec4 a4(1.1f, 2.4f, 3.7f, 1.0f); kazu::blast::vec4 b4(4.2f, 5.6f, 6.5f, 1.0f); std::cout << a4 << std::endl; std::cout << b4 << std::endl; std::cout << cross(a4, b4) << std::endl; std::cout << a4.swizzle2<0, 0>() << std::endl; std::cout << b4.zzz() << a4.wwww() << std::endl; return 0; } //////////////////////////////////////////////////////////////////////////