diff options
Diffstat (limited to 'debian/fireflies/fireflies-2.08/libgfx/include/gfx/vec3.h')
-rw-r--r-- | debian/fireflies/fireflies-2.08/libgfx/include/gfx/vec3.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/debian/fireflies/fireflies-2.08/libgfx/include/gfx/vec3.h b/debian/fireflies/fireflies-2.08/libgfx/include/gfx/vec3.h new file mode 100644 index 00000000..22d37394 --- /dev/null +++ b/debian/fireflies/fireflies-2.08/libgfx/include/gfx/vec3.h @@ -0,0 +1,184 @@ +#ifndef GFXVEC3_INCLUDED // -*- C++ -*- +#define GFXVEC3_INCLUDED +#if !defined(__GNUC__) +# pragma once +#endif + +/************************************************************************ + + 3D Vector class + + $Id: vec3.h 427 2004-09-27 04:45:31Z garland $ + + ************************************************************************/ + +#include "vec2.h" + +namespace gfx +{ + +template<class T> +class TVec3 { +private: + T elt[3]; + +public: + // Standard constructors + // + TVec3(T s=0) { *this = s; } + TVec3(T x, T y, T z) { elt[0]=x; elt[1]=y; elt[2]=z; } + + // Copy constructors & assignment operators + template<class U> TVec3(const TVec3<U>& v) { *this = v; } +#ifndef STDMIX_INCLUDED + // This is now a standard constructor, except when compiling legacy MixKit + // code. + template<class U> TVec3(const U v[3]) + { elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; } +#else + // For MixKit code, we need these constructors instead. + // They SHOULD NOT be used in new code. + TVec3(const float *v) { elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; } + TVec3(const double *v) { elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; } +#endif + template<class U> TVec3& operator=(const TVec3<U>& v) + { elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; return *this; } + TVec3& operator=(T s) { elt[0]=elt[1]=elt[2]=s; return *this; } + + // Descriptive interface + // + typedef T value_type; + static int dim() { return 3; } + + + // Access methods + // + operator T*() { return elt; } + operator const T*() const { return elt; } + +#ifndef HAVE_CASTING_LIMITS + T& operator[](int i) { return elt[i]; } + T operator[](int i) const { return elt[i]; } + operator const T*() { return elt; } +#endif + + + // Assignment and in-place arithmetic methods + // + inline TVec3& operator+=(const TVec3& v); + inline TVec3& operator-=(const TVec3& v); + inline TVec3& operator*=(T s); + inline TVec3& operator/=(T s); +}; + +//////////////////////////////////////////////////////////////////////// +// +// Method definitions +// + +template<class T> inline TVec3<T>& TVec3<T>::operator+=(const TVec3<T>& v) + { elt[0] += v[0]; elt[1] += v[1]; elt[2] += v[2]; return *this; } + +template<class T> inline TVec3<T>& TVec3<T>::operator-=(const TVec3<T>& v) + { elt[0] -= v[0]; elt[1] -= v[1]; elt[2] -= v[2]; return *this; } + +template<class T> inline TVec3<T>& TVec3<T>::operator*=(T s) + { elt[0] *= s; elt[1] *= s; elt[2] *= s; return *this; } + +template<class T> inline TVec3<T>& TVec3<T>::operator/=(T s) + { elt[0] /= s; elt[1] /= s; elt[2] /= s; return *this; } + + +//////////////////////////////////////////////////////////////////////// +// +// Operator definitions +// + +template<class T> +inline TVec3<T> operator+(const TVec3<T> &u, const TVec3<T>& v) + { return TVec3<T>(u[0]+v[0], u[1]+v[1], u[2]+v[2]); } + +template<class T> +inline TVec3<T> operator-(const TVec3<T> &u, const TVec3<T>& v) + { return TVec3<T>(u[0]-v[0], u[1]-v[1], u[2]-v[2]); } + +template<class T> inline TVec3<T> operator-(const TVec3<T> &v) + { return TVec3<T>(-v[0], -v[1], -v[2]); } + +#if _MSC_VER>=1200 +// Normally, we use the <class T, class N> construct below to allow the scalar +// argument to be different than the template type. This, for example, allows +// the user to write things like v/2. Unfortunately, Microsoft VC6.0 (aka +// v1200) gets confused by this. We used to include explicit versions for the +// case of int's, but this was causing silent (and incorrect) coercion of +// floats to ints. +// + template<class T> inline TVec3<T> operator*(T s, const TVec3<T> &v) + { return TVec3<T>(v[0]*s, v[1]*s, v[2]*s); } + template<class T> inline TVec3<T> operator*(const TVec3<T> &v, T s) + { return s*v; } + + template<class T> inline TVec3<T> operator/(const TVec3<T> &v, T s) + { return TVec3<T>(v[0]/s, v[1]/s, v[2]/s); } +#else + template<class T, class N> inline TVec3<T> operator*(N s, const TVec3<T> &v) + { return TVec3<T>(v[0]*s, v[1]*s, v[2]*s); } + template<class T, class N> inline TVec3<T> operator*(const TVec3<T> &v, N s) + { return s*v; } + + template<class T, class N> inline TVec3<T> operator/(const TVec3<T> &v, N s) + { return TVec3<T>(v[0]/s, v[1]/s, v[2]/s); } +#endif + +template<class T> inline T operator*(const TVec3<T> &u, const TVec3<T>& v) + { return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]; } + +template<class T> inline TVec3<T> cross(const TVec3<T>& u, const TVec3<T>& v) +{ + return TVec3<T>( u[1]*v[2] - v[1]*u[2], + -u[0]*v[2] + v[0]*u[2], + u[0]*v[1] - v[0]*u[1] ); +} + +template<class T> +inline TVec3<T> operator^(const TVec3<T>& u, const TVec3<T>& v) + { return cross(u, v); } + + +template<class T> +inline std::ostream &operator<<(std::ostream &out, const TVec3<T>& v) + { return out << v[0] << " " << v[1] << " " << v[2]; } + +template<class T> +inline std::istream &operator>>(std::istream &in, TVec3<T>& v) + { return in >> v[0] >> v[1] >> v[2]; } + +//////////////////////////////////////////////////////////////////////// +// +// Misc. function definitions +// + +template<class T> inline T norm2(const TVec3<T>& v) { return v*v; } +template<class T> inline T norm(const TVec3<T>& v) { return sqrt(norm2(v)); } + +template<class T> inline void unitize(TVec3<T>& v) +{ + T l = norm2(v); + if( l!=1.0 && l!=0.0 ) v /= sqrt(l); +} + +template<class T> inline TVec2<T> proj(const TVec3<T>& v) +{ + TVec2<T> u(v[0], v[1]); + if( v[2]!=1.0 && v[2]!=0.0 ) + u /= v[2]; + return u; +} + +typedef TVec3<double> Vec3; +typedef TVec3<float> Vec3f; + +} // namespace gfx + +// GFXVEC3_INCLUDED +#endif |