/extern/prmath/vector3float.hpp
C++ Header | 665 lines | 504 code | 97 blank | 64 comment | 29 complexity | 9f8e7f8edbc0552398544774561bc374 MD5 | raw file
Possible License(s): MIT
- /*
- Twilight Prophecy SDK
- A multi-platform development system for virtual reality and multimedia.
- Copyright (C) 1997-2003 Twilight 3D Finland Oy Ltd.
- */
- /*
- Abstract:
- Meta Expression Template based specialization of prmath::Vector3<float>
-
- Reference material:
- Jim Blinn's Corner: Notation, Notation, Notation ISBN 1-55860-860-5
- Tomas Arce: Faster Vector Math Using Templates http://www.flipcode.com/tutorials/tut_fastmath.shtml
- */
- #ifndef PRMATH_VECTOR3FLOAT_HPP
- #define PRMATH_VECTOR3FLOAT_HPP
- #ifndef PRMATH_VECTOR3_HPP
- #error prmath: "do not include this header yourself!"
- #endif
- #include "metavector.hpp"
- #ifdef PRMATH_METAVECTOR_ENABLE
- namespace prmath
- {
- // expression
- template <typename E>
- class MetaExpV3F
- {
- E exp;
- public:
-
- metainline MetaExpV3F(const E& e)
- : exp(e)
- {
- }
- metainline float operator [] (const int index) const
- {
- return exp[index];
- }
- metainline MetaExpV3F operator + () const
- {
- return *this;
- }
- metainline const MetaExpV3F< MetaNEG<float,E> > operator - () const
- {
- return MetaExpV3F< MetaNEG<float,E> >(exp);
- }
- };
- template <>
- class MetaExpV3F<float>
- {
- float exp;
- public:
-
- metainline MetaExpV3F(const float& e)
- : exp(e)
- {
- }
- metainline float operator [] (const int index) const
- {
- return exp;
- }
- };
- // vector3<float>
- template <>
- struct Vector3<float> : BaseVector<float,3>
- {
- // members
- union { float x,r; };
- union { float y,g; };
- union { float z,b; };
- // constructors
- metainline Vector3()
- {
- }
- metainline Vector3(float sx, float sy, float sz)
- : x(sx), y(sy), z(sz)
- {
- }
- metainline Vector3(const float v[])
- : x(v[0]), y(v[1]), z(v[2])
- {
- }
- metainline Vector3(const Vector3& v)
- : x(v.x), y(v.y), z(v.z)
- {
- }
- metainline Vector3(float v)
- : x(v), y(v), z(v)
- {
- }
- template <typename E>
- metainline Vector3(const MetaExpV3F<E>& exp)
- {
- x = exp[0];
- y = exp[1];
- z = exp[2];
- }
- // operators
- template <typename E>
- metainline Vector3<float>& operator += (const MetaExpV3F<E>& exp)
- {
- x += exp[0];
- y += exp[1];
- z += exp[2];
- return *this;
- }
- template <typename E>
- metainline Vector3<float>& operator -= (const MetaExpV3F<E>& exp)
- {
- x -= exp[0];
- y -= exp[1];
- z -= exp[2];
- return *this;
- }
- template <typename E>
- metainline Vector3<float>& operator *= (const MetaExpV3F<E>& exp)
- {
- x *= exp[0];
- y *= exp[1];
- z *= exp[2];
- return *this;
- }
- template <typename E>
- metainline Vector3<float>& operator = (const MetaExpV3F<E>& exp)
- {
- x = exp[0];
- y = exp[1];
- z = exp[2];
- return *this;
- }
- metainline Vector3 operator + () const
- {
- return *this;
- }
- metainline Vector3 operator - () const
- {
- return Vector3(-x,-y,-z);
- }
- metainline Vector3& operator += (const Vector3& v)
- {
- x += v.x;
- y += v.y;
- z += v.z;
- return *this;
- }
- metainline Vector3& operator -= (const Vector3& v)
- {
- x -= v.x;
- y -= v.y;
- z -= v.z;
- return *this;
- }
- metainline Vector3& operator *= (const Vector3& v)
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- return *this;
- }
- metainline Vector3& operator = (const Vector3& v)
- {
- x = v.x;
- y = v.y;
- z = v.z;
- return *this;
- }
- metainline Vector3& operator = (float v)
- {
- x = v;
- y = v;
- z = v;
- return *this;
- }
- metainline Vector3& operator *= (float s)
- {
- x *= s;
- y *= s;
- z *= s;
- return *this;
- }
- metainline Vector3& operator /= (float s)
- {
- assert( s != 0 );
- float is = 1 / s;
- x *= is;
- y *= is;
- z *= is;
- return *this;
- }
- // methods
- metainline void Normalize()
- {
- float s = x*x + y*y + z*z;
- if ( s != 0 )
- {
- s = 1 / static_cast<float>(sqrt(s));
- x *= s;
- y *= s;
- z *= s;
- }
- }
- metainline void SetVector(float sx, float sy, float sz)
- {
- x = sx;
- y = sy;
- z = sz;
- }
- metainline void SetVector(float v)
- {
- x = v;
- y = v;
- z = v;
- }
- };
- // meta operators
- // exp + exp
- template <typename A, typename B>
- metainline const MetaExpV3F< MetaADD< float,MetaExpV3F<A>,MetaExpV3F<B> > >
- operator + (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaADD< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp + vec3f
- template <typename A>
- metainline const MetaExpV3F< MetaADD< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
- operator + (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- typedef MetaADD< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f + exp
- template <typename B>
- metainline const MetaExpV3F< MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
- operator + (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f + vec3f
- metainline const MetaExpV3F< MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
- operator + (const Vector3<float>& a, const Vector3<float>& b)
- {
- typedef MetaADD< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp - exp
- template <typename A, typename B>
- metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F<A>,MetaExpV3F<B> > >
- operator - (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaSUB< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp - vec3f
- template <typename A>
- metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
- operator - (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- typedef MetaSUB< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f - exp
- template <typename B>
- metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
- operator - (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f - vec3f
- metainline const MetaExpV3F< MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
- operator - (const Vector3<float>& a, const Vector3<float>& b)
- {
- typedef MetaSUB< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp * exp
- template <typename A, typename B>
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<B> > >
- operator * (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp * vec3f
- template <typename A>
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
- operator * (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp * float
- template <typename A>
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<float> > >
- operator * (const MetaExpV3F<A>& a, const float& b)
- {
- typedef MetaMUL< float,MetaExpV3F<A>,MetaExpV3F<float> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f * exp
- template <typename B>
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
- operator * (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f * vec3f
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
- operator * (const Vector3<float>& a, const Vector3<float>& b)
- {
- typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f * float
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > >
- operator * (const Vector3<float>& a, const float& b)
- {
- typedef MetaMUL< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // float * exp
- template <typename B>
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<float>,MetaExpV3F<B> > >
- operator * (const float& a, const MetaExpV3F<B>& b)
- {
- typedef MetaMUL< float,MetaExpV3F<float>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // float * vec3f
- metainline const MetaExpV3F< MetaMUL< float,MetaExpV3F<float>,MetaExpV3F< Vector3<float> > > >
- operator * (const float& a, Vector3<float>& b)
- {
- typedef MetaMUL< float,MetaExpV3F<float>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp / exp
- template <typename A, typename B>
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<B> > >
- operator / (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp / vec3f
- template <typename A>
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
- operator / (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp / float
- template <typename A>
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<float> > >
- operator / (const MetaExpV3F<A>& a, const float& b)
- {
- typedef MetaDIV< float,MetaExpV3F<A>,MetaExpV3F<float> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f / exp
- template <typename B>
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
- operator / (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f / vec3f
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
- operator / (const Vector3<float>& a, const Vector3<float>& b)
- {
- typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f / float
- metainline const MetaExpV3F< MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > >
- operator / (const Vector3<float>& a, const float& b)
- {
- typedef MetaDIV< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<float> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp == exp
- template <typename A, typename B>
- metainline bool operator == (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return false;
- }
- return true;
- }
- // vec3f == exp
- template <typename B>
- metainline bool operator == (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return false;
- }
- return true;
- }
- // exp == vec3f
- template <typename A>
- metainline bool operator == (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return false;
- }
- return true;
- }
- // exp != exp
- template <typename A, typename B>
- metainline bool operator != (const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return true;
- }
- return false;
- }
- // vec3f != exp
- template <typename B>
- metainline bool operator != (const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return true;
- }
- return false;
- }
- // exp != vec3f
- template <typename A>
- metainline bool operator != (const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- for ( int i=0; i<3; ++i )
- {
- if ( a[i] != b[i] )
- return true;
- }
- return false;
- }
- // meta functions
- // exp x exp
- template <typename A, typename B>
- metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F<B> > >
- CrossProduct(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // exp x vec3f
- template <typename A>
- metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > >
- CrossProduct(const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- typedef MetaCROSS3< float,MetaExpV3F<A>,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f x exp
- template <typename B>
- metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > >
- CrossProduct(const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- typedef MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F<B> > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }
- // vec3f x vec3f
- /* metainline const MetaExpV3F< MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > >
- CrossProduct(const Vector3<float>& a, const Vector3<float>& b)
- {
- typedef MetaCROSS3< float,MetaExpV3F< Vector3<float> >,MetaExpV3F< Vector3<float> > > exp;
- return MetaExpV3F<exp>(exp(a,b));
- }*/
- metainline Vector3<float>
- CrossProduct(const Vector3<float>& a, const Vector3<float>& b)
- {
- return Vector3<float>(
- a.y * b.z - a.z * b.y,
- a.z * b.x - a.x * b.z,
- a.x * b.y - a.y * b.x);
- }
- // exp . exp
- template <typename A, typename B>
- metainline float DotProduct(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b)
- {
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
- }
- // exp . vec3f
- template <typename A>
- metainline float DotProduct(const MetaExpV3F<A>& a, const Vector3<float>& b)
- {
- return a[0] * b.x + a[1] * b.y + a[2] * b.z;
- }
- // vec3f . exp
- template <typename B>
- metainline float DotProduct(const Vector3<float>& a, const MetaExpV3F<B>& b)
- {
- return a.x * b[0] + a.y * b[1] + a.z * b[2];
- }
- // vec3f . vec3f
- metainline float DotProduct(const Vector3<float>& a, const Vector3<float>& b)
- {
- return a.x * b.x + a.y * b.y + a.z * b.z;
- }
- template <typename E>
- metainline float LengthSquared(const MetaExpV3F<E>& exp)
- {
- return DotProduct(exp,exp);
- }
- template <typename E>
- metainline float Length(const MetaExpV3F<E>& exp)
- {
- return static_cast<float>(sqrt(LengthSquared(exp)));
- }
- template <typename E>
- metainline Vector3<float> Normalize(const MetaExpV3F<E>& exp)
- {
- float s = LengthSquared(exp);
- if ( s == 0 )
- return Vector3<float>(0,0,0);
-
- s = 1 / static_cast<float>(sqrt(s));
- return Vector3<float>(exp * s);
- }
- template <typename A, typename B>
- metainline Vector3<float> Reflect(const MetaExpV3F<A>& v, const MetaExpV3F<B>& normal)
- {
- float s = DotProduct(v,normal) * 2;
- return Vector3<float>(v + normal * s);
- }
- template <typename B>
- metainline Vector3<float> Reflect(const Vector3<float>& v, const MetaExpV3F<B>& normal)
- {
- float s = DotProduct(v,normal) * 2;
- return Vector3<float>(v + normal * s);
- }
- template <typename A>
- metainline Vector3<float> Reflect(const MetaExpV3F<A>& v, const Vector3<float>& normal)
- {
- float s = DotProduct(v,normal) * 2;
- return Vector3<float>(v + normal * s);
- }
- template <typename A, typename B>
- metainline Vector3<float> Lerp(const MetaExpV3F<A>& a, const MetaExpV3F<B>& b, float time)
- {
- return Vector3<float>(a + (b - a) * time);
- }
- template <typename B>
- metainline Vector3<float> Lerp(const Vector3<float>& a, const MetaExpV3F<B>& b, float time)
- {
- return Vector3<float>(a + (b - a) * time);
- }
- template <typename A>
- metainline Vector3<float> Lerp(const MetaExpV3F<A>& a, const Vector3<float>& b, float time)
- {
- return Vector3<float>(a + (b - a) * time);
- }
- } // namespace prmath
- #undef metainline
- #undef PRMATH_METAVECTOR_ENABLE
- #endif
- #endif