Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / include / OpenEXR / ImathVec.h
diff --git a/3rdparty/include/OpenEXR/ImathVec.h b/3rdparty/include/OpenEXR/ImathVec.h
new file mode 100644 (file)
index 0000000..b7adc5f
--- /dev/null
@@ -0,0 +1,1426 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMATHVEC_H
+#define INCLUDED_IMATHVEC_H
+
+//----------------------------------------------------
+//
+//     2D and 3D point/vector class templates!
+//
+//----------------------------------------------------
+
+#include "ImathExc.h"
+#include "ImathLimits.h"
+#include "ImathMath.h"
+
+#include <iostream>
+
+#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
+// suppress exception specification warnings
+#pragma warning(disable:4290)
+#endif
+
+
+namespace Imath {
+
+
+template <class T> class Vec2
+{
+  public:
+
+    //-------------------
+    // Access to elements
+    //-------------------
+
+    T                  x, y;
+
+    T &                        operator [] (int i);
+    const T &          operator [] (int i) const;
+
+
+    //-------------
+    // Constructors
+    //-------------
+
+    Vec2 ();                        // no initialization
+    explicit Vec2 (T a);            // (a a)
+    Vec2 (T a, T b);                // (a b)
+
+
+    //---------------------------------
+    // Copy constructors and assignment
+    //---------------------------------
+
+    Vec2 (const Vec2 &v);
+    template <class S> Vec2 (const Vec2<S> &v);
+
+    const Vec2 &       operator = (const Vec2 &v);
+
+
+    //----------------------
+    // Compatibility with Sb
+    //----------------------
+
+    template <class S>
+    void               setValue (S a, S b);
+
+    template <class S>
+    void               setValue (const Vec2<S> &v);
+
+    template <class S>
+    void               getValue (S &a, S &b) const;
+
+    template <class S>
+    void               getValue (Vec2<S> &v) const;
+
+    T *                        getValue ();
+    const T *          getValue () const;
+
+    
+    //---------
+    // Equality
+    //---------
+
+    template <class S>
+    bool               operator == (const Vec2<S> &v) const;
+
+    template <class S>
+    bool               operator != (const Vec2<S> &v) const;
+
+
+    //-----------------------------------------------------------------------
+    // Compare two vectors and test if they are "approximately equal":
+    //
+    // equalWithAbsError (v, e)
+    //
+    //     Returns true if the coefficients of this and v are the same with
+    //     an absolute error of no more than e, i.e., for all i
+    //
+    //      abs (this[i] - v[i]) <= e
+    //
+    // equalWithRelError (v, e)
+    //
+    //     Returns true if the coefficients of this and v are the same with
+    //     a relative error of no more than e, i.e., for all i
+    //
+    //      abs (this[i] - v[i]) <= e * abs (this[i])
+    //-----------------------------------------------------------------------
+
+    bool               equalWithAbsError (const Vec2<T> &v, T e) const;
+    bool               equalWithRelError (const Vec2<T> &v, T e) const;
+
+    //------------
+    // Dot product
+    //------------
+
+    T                  dot (const Vec2 &v) const;
+    T                  operator ^ (const Vec2 &v) const;
+
+
+    //------------------------------------------------
+    // Right-handed cross product, i.e. z component of
+    // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
+    //------------------------------------------------
+
+    T                  cross (const Vec2 &v) const;
+    T                  operator % (const Vec2 &v) const;
+
+
+    //------------------------
+    // Component-wise addition
+    //------------------------
+
+    const Vec2 &       operator += (const Vec2 &v);
+    Vec2               operator + (const Vec2 &v) const;
+
+
+    //---------------------------
+    // Component-wise subtraction
+    //---------------------------
+
+    const Vec2 &       operator -= (const Vec2 &v);
+    Vec2               operator - (const Vec2 &v) const;
+
+
+    //------------------------------------
+    // Component-wise multiplication by -1
+    //------------------------------------
+
+    Vec2               operator - () const;
+    const Vec2 &       negate ();
+
+
+    //------------------------------
+    // Component-wise multiplication
+    //------------------------------
+
+    const Vec2 &       operator *= (const Vec2 &v);
+    const Vec2 &       operator *= (T a);
+    Vec2               operator * (const Vec2 &v) const;
+    Vec2               operator * (T a) const;
+
+
+    //------------------------
+    // Component-wise division
+    //------------------------
+
+    const Vec2 &       operator /= (const Vec2 &v);
+    const Vec2 &       operator /= (T a);
+    Vec2               operator / (const Vec2 &v) const;
+    Vec2               operator / (T a) const;
+
+
+    //----------------------------------------------------------------
+    // Length and normalization:  If v.length() is 0.0, v.normalize()
+    // and v.normalized() produce a null vector; v.normalizeExc() and
+    // v.normalizedExc() throw a NullVecExc.
+    // v.normalizeNonNull() and v.normalizedNonNull() are slightly
+    // faster than the other normalization routines, but if v.length()
+    // is 0.0, the result is undefined.
+    //----------------------------------------------------------------
+
+    T                  length () const;
+    T                  length2 () const;
+
+    const Vec2 &       normalize ();           // modifies *this
+    const Vec2 &       normalizeExc () throw (Iex::MathExc);
+    const Vec2 &       normalizeNonNull ();
+
+    Vec2<T>            normalized () const;    // does not modify *this
+    Vec2<T>            normalizedExc () const throw (Iex::MathExc);
+    Vec2<T>            normalizedNonNull () const;
+
+
+    //--------------------------------------------------------
+    // Number of dimensions, i.e. number of elements in a Vec2
+    //--------------------------------------------------------
+
+    static unsigned int        dimensions() {return 2;}
+
+
+    //-------------------------------------------------
+    // Limitations of type T (see also class limits<T>)
+    //-------------------------------------------------
+
+    static T           baseTypeMin()           {return limits<T>::min();}
+    static T           baseTypeMax()           {return limits<T>::max();}
+    static T           baseTypeSmallest()      {return limits<T>::smallest();}
+    static T           baseTypeEpsilon()       {return limits<T>::epsilon();}
+
+
+    //--------------------------------------------------------------
+    // Base type -- in templates, which accept a parameter, V, which
+    // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
+    // V::BaseType
+    //--------------------------------------------------------------
+
+    typedef T          BaseType;
+};
+
+
+template <class T> class Vec3
+{
+  public:
+
+    //-------------------
+    // Access to elements
+    //-------------------
+
+    T                  x, y, z;
+
+    T &                        operator [] (int i);
+    const T &          operator [] (int i) const;
+
+
+    //-------------
+    // Constructors
+    //-------------
+
+    Vec3 ();                      // no initialization
+    explicit Vec3 (T a);           // (a a a)
+    Vec3 (T a, T b, T c);         // (a b c)
+
+
+    //---------------------------------
+    // Copy constructors and assignment
+    //---------------------------------
+
+    Vec3 (const Vec3 &v);
+    template <class S> Vec3 (const Vec3<S> &v);
+
+    const Vec3 &       operator = (const Vec3 &v);
+
+
+    //----------------------
+    // Compatibility with Sb
+    //----------------------
+
+    template <class S>
+    void               setValue (S a, S b, S c);
+
+    template <class S>
+    void               setValue (const Vec3<S> &v);
+
+    template <class S>
+    void               getValue (S &a, S &b, S &c) const;
+
+    template <class S>
+    void               getValue (Vec3<S> &v) const;
+
+    T *                        getValue();
+    const T *          getValue() const;
+
+
+    //---------
+    // Equality
+    //---------
+
+    template <class S>
+    bool               operator == (const Vec3<S> &v) const;
+
+    template <class S>
+    bool               operator != (const Vec3<S> &v) const;
+
+    //-----------------------------------------------------------------------
+    // Compare two vectors and test if they are "approximately equal":
+    //
+    // equalWithAbsError (v, e)
+    //
+    //     Returns true if the coefficients of this and v are the same with
+    //     an absolute error of no more than e, i.e., for all i
+    //
+    //      abs (this[i] - v[i]) <= e
+    //
+    // equalWithRelError (v, e)
+    //
+    //     Returns true if the coefficients of this and v are the same with
+    //     a relative error of no more than e, i.e., for all i
+    //
+    //      abs (this[i] - v[i]) <= e * abs (this[i])
+    //-----------------------------------------------------------------------
+
+    bool               equalWithAbsError (const Vec3<T> &v, T e) const;
+    bool               equalWithRelError (const Vec3<T> &v, T e) const;
+
+    //------------
+    // Dot product
+    //------------
+
+    T                  dot (const Vec3 &v) const;
+    T                  operator ^ (const Vec3 &v) const;
+
+
+    //---------------------------
+    // Right-handed cross product
+    //---------------------------
+
+    Vec3               cross (const Vec3 &v) const;
+    const Vec3 &       operator %= (const Vec3 &v);
+    Vec3               operator % (const Vec3 &v) const;
+
+
+    //------------------------
+    // Component-wise addition
+    //------------------------
+
+    const Vec3 &       operator += (const Vec3 &v);
+    Vec3               operator + (const Vec3 &v) const;
+
+
+    //---------------------------
+    // Component-wise subtraction
+    //---------------------------
+
+    const Vec3 &       operator -= (const Vec3 &v);
+    Vec3               operator - (const Vec3 &v) const;
+
+
+    //------------------------------------
+    // Component-wise multiplication by -1
+    //------------------------------------
+
+    Vec3               operator - () const;
+    const Vec3 &       negate ();
+
+
+    //------------------------------
+    // Component-wise multiplication
+    //------------------------------
+
+    const Vec3 &       operator *= (const Vec3 &v);
+    const Vec3 &       operator *= (T a);
+    Vec3               operator * (const Vec3 &v) const;
+    Vec3               operator * (T a) const;
+
+
+    //------------------------
+    // Component-wise division
+    //------------------------
+
+    const Vec3 &       operator /= (const Vec3 &v);
+    const Vec3 &       operator /= (T a);
+    Vec3               operator / (const Vec3 &v) const;
+    Vec3               operator / (T a) const;
+
+
+    //----------------------------------------------------------------
+    // Length and normalization:  If v.length() is 0.0, v.normalize()
+    // and v.normalized() produce a null vector; v.normalizeExc() and
+    // v.normalizedExc() throw a NullVecExc.
+    // v.normalizeNonNull() and v.normalizedNonNull() are slightly
+    // faster than the other normalization routines, but if v.length()
+    // is 0.0, the result is undefined.
+    //----------------------------------------------------------------
+
+    T                  length () const;
+    T                  length2 () const;
+
+    const Vec3 &       normalize ();           // modifies *this
+    const Vec3 &       normalizeExc () throw (Iex::MathExc);
+    const Vec3 &       normalizeNonNull ();
+
+    Vec3<T>            normalized () const;    // does not modify *this
+    Vec3<T>            normalizedExc () const throw (Iex::MathExc);
+    Vec3<T>            normalizedNonNull () const;
+
+
+    //--------------------------------------------------------
+    // Number of dimensions, i.e. number of elements in a Vec3
+    //--------------------------------------------------------
+
+    static unsigned int        dimensions() {return 3;}
+
+
+    //-------------------------------------------------
+    // Limitations of type T (see also class limits<T>)
+    //-------------------------------------------------
+
+    static T           baseTypeMin()           {return limits<T>::min();}
+    static T           baseTypeMax()           {return limits<T>::max();}
+    static T           baseTypeSmallest()      {return limits<T>::smallest();}
+    static T           baseTypeEpsilon()       {return limits<T>::epsilon();}
+
+
+    //--------------------------------------------------------------
+    // Base type -- in templates, which accept a parameter, V, which
+    // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
+    // V::BaseType
+    //--------------------------------------------------------------
+
+    typedef T          BaseType;
+};
+
+
+//--------------
+// Stream output
+//--------------
+
+template <class T>
+std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
+
+template <class T>
+std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
+
+
+//----------------------------------------------------
+// Reverse multiplication: S * Vec2<T> and S * Vec3<T>
+//----------------------------------------------------
+
+template <class T> Vec2<T>     operator * (T a, const Vec2<T> &v);
+template <class T> Vec3<T>     operator * (T a, const Vec3<T> &v);
+
+
+//-------------------------
+// Typedefs for convenience
+//-------------------------
+
+typedef Vec2 <short>  V2s;
+typedef Vec2 <int>    V2i;
+typedef Vec2 <float>  V2f;
+typedef Vec2 <double> V2d;
+typedef Vec3 <short>  V3s;
+typedef Vec3 <int>    V3i;
+typedef Vec3 <float>  V3f;
+typedef Vec3 <double> V3d;
+
+
+//-------------------------------------------------------------------
+// Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int>
+//-------------------------------------------------------------------
+
+// Vec2<short>
+
+template <> short
+Vec2<short>::length () const;
+
+template <> const Vec2<short> &
+Vec2<short>::normalize ();
+
+template <> const Vec2<short> &
+Vec2<short>::normalizeExc () throw (Iex::MathExc);
+
+template <> const Vec2<short> &
+Vec2<short>::normalizeNonNull ();
+
+template <> Vec2<short>
+Vec2<short>::normalized () const;
+
+template <> Vec2<short>
+Vec2<short>::normalizedExc () const throw (Iex::MathExc);
+
+template <> Vec2<short>
+Vec2<short>::normalizedNonNull () const;
+
+
+// Vec2<int>
+
+template <> int
+Vec2<int>::length () const;
+
+template <> const Vec2<int> &
+Vec2<int>::normalize ();
+
+template <> const Vec2<int> &
+Vec2<int>::normalizeExc () throw (Iex::MathExc);
+
+template <> const Vec2<int> &
+Vec2<int>::normalizeNonNull ();
+
+template <> Vec2<int>
+Vec2<int>::normalized () const;
+
+template <> Vec2<int>
+Vec2<int>::normalizedExc () const throw (Iex::MathExc);
+
+template <> Vec2<int>
+Vec2<int>::normalizedNonNull () const;
+
+
+// Vec3<short>
+
+template <> short
+Vec3<short>::length () const;
+
+template <> const Vec3<short> &
+Vec3<short>::normalize ();
+
+template <> const Vec3<short> &
+Vec3<short>::normalizeExc () throw (Iex::MathExc);
+
+template <> const Vec3<short> &
+Vec3<short>::normalizeNonNull ();
+
+template <> Vec3<short>
+Vec3<short>::normalized () const;
+
+template <> Vec3<short>
+Vec3<short>::normalizedExc () const throw (Iex::MathExc);
+
+template <> Vec3<short>
+Vec3<short>::normalizedNonNull () const;
+
+
+// Vec3<int>
+
+template <> int
+Vec3<int>::length () const;
+
+template <> const Vec3<int> &
+Vec3<int>::normalize ();
+
+template <> const Vec3<int> &
+Vec3<int>::normalizeExc () throw (Iex::MathExc);
+
+template <> const Vec3<int> &
+Vec3<int>::normalizeNonNull ();
+
+template <> Vec3<int>
+Vec3<int>::normalized () const;
+
+template <> Vec3<int>
+Vec3<int>::normalizedExc () const throw (Iex::MathExc);
+
+template <> Vec3<int>
+Vec3<int>::normalizedNonNull () const;
+
+
+//------------------------
+// Implementation of Vec2:
+//------------------------
+
+template <class T>
+inline T &
+Vec2<T>::operator [] (int i)
+{
+    return (&x)[i];
+}
+
+template <class T>
+inline const T &
+Vec2<T>::operator [] (int i) const
+{
+    return (&x)[i];
+}
+
+template <class T>
+inline
+Vec2<T>::Vec2 ()
+{
+    // empty
+}
+
+template <class T>
+inline
+Vec2<T>::Vec2 (T a)
+{
+    x = y = a;
+}
+
+template <class T>
+inline
+Vec2<T>::Vec2 (T a, T b)
+{
+    x = a;
+    y = b;
+}
+
+template <class T>
+inline
+Vec2<T>::Vec2 (const Vec2 &v)
+{
+    x = v.x;
+    y = v.y;
+}
+
+template <class T>
+template <class S>
+inline
+Vec2<T>::Vec2 (const Vec2<S> &v)
+{
+    x = T (v.x);
+    y = T (v.y);
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator = (const Vec2 &v)
+{
+    x = v.x;
+    y = v.y;
+    return *this;
+}
+
+template <class T>
+template <class S>
+inline void
+Vec2<T>::setValue (S a, S b)
+{
+    x = T (a);
+    y = T (b);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec2<T>::setValue (const Vec2<S> &v)
+{
+    x = T (v.x);
+    y = T (v.y);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec2<T>::getValue (S &a, S &b) const
+{
+    a = S (x);
+    b = S (y);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec2<T>::getValue (Vec2<S> &v) const
+{
+    v.x = S (x);
+    v.y = S (y);
+}
+
+template <class T>
+inline T *
+Vec2<T>::getValue()
+{
+    return (T *) &x;
+}
+
+template <class T>
+inline const T *
+Vec2<T>::getValue() const
+{
+    return (const T *) &x;
+}
+
+template <class T>
+template <class S>
+inline bool
+Vec2<T>::operator == (const Vec2<S> &v) const
+{
+    return x == v.x && y == v.y;
+}
+
+template <class T>
+template <class S>
+inline bool
+Vec2<T>::operator != (const Vec2<S> &v) const
+{
+    return x != v.x || y != v.y;
+}
+
+template <class T>
+bool
+Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
+{
+    for (int i = 0; i < 2; i++)
+       if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+           return false;
+
+    return true;
+}
+
+template <class T>
+bool
+Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
+{
+    for (int i = 0; i < 2; i++)
+       if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+           return false;
+
+    return true;
+}
+
+template <class T>
+inline T
+Vec2<T>::dot (const Vec2 &v) const
+{
+    return x * v.x + y * v.y;
+}
+
+template <class T>
+inline T
+Vec2<T>::operator ^ (const Vec2 &v) const
+{
+    return dot (v);
+}
+
+template <class T>
+inline T
+Vec2<T>::cross (const Vec2 &v) const
+{
+    return x * v.y - y * v.x;
+
+}
+
+template <class T>
+inline T
+Vec2<T>::operator % (const Vec2 &v) const
+{
+    return x * v.y - y * v.x;
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator += (const Vec2 &v)
+{
+    x += v.x;
+    y += v.y;
+    return *this;
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator + (const Vec2 &v) const
+{
+    return Vec2 (x + v.x, y + v.y);
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator -= (const Vec2 &v)
+{
+    x -= v.x;
+    y -= v.y;
+    return *this;
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator - (const Vec2 &v) const
+{
+    return Vec2 (x - v.x, y - v.y);
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator - () const
+{
+    return Vec2 (-x, -y);
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::negate ()
+{
+    x = -x;
+    y = -y;
+    return *this;
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator *= (const Vec2 &v)
+{
+    x *= v.x;
+    y *= v.y;
+    return *this;
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator *= (T a)
+{
+    x *= a;
+    y *= a;
+    return *this;
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator * (const Vec2 &v) const
+{
+    return Vec2 (x * v.x, y * v.y);
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator * (T a) const
+{
+    return Vec2 (x * a, y * a);
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator /= (const Vec2 &v)
+{
+    x /= v.x;
+    y /= v.y;
+    return *this;
+}
+
+template <class T>
+inline const Vec2<T> &
+Vec2<T>::operator /= (T a)
+{
+    x /= a;
+    y /= a;
+    return *this;
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator / (const Vec2 &v) const
+{
+    return Vec2 (x / v.x, y / v.y);
+}
+
+template <class T>
+inline Vec2<T>
+Vec2<T>::operator / (T a) const
+{
+    return Vec2 (x / a, y / a);
+}
+
+template <class T>
+inline T
+Vec2<T>::length () const
+{
+    return Math<T>::sqrt (dot (*this));
+}
+
+template <class T>
+inline T
+Vec2<T>::length2 () const
+{
+    return dot (*this);
+}
+
+template <class T>
+const Vec2<T> &
+Vec2<T>::normalize ()
+{
+    T l = length();
+
+    if (l != 0)
+    {
+       x /= l;
+       y /= l;
+    }
+
+    return *this;
+}
+
+template <class T>
+const Vec2<T> &
+Vec2<T>::normalizeExc () throw (Iex::MathExc)
+{
+    T l = length();
+
+    if (l == 0)
+       throw NullVecExc ("Cannot normalize null vector.");
+
+    x /= l;
+    y /= l;
+    return *this;
+}
+
+template <class T>
+inline
+const Vec2<T> &
+Vec2<T>::normalizeNonNull ()
+{
+    T l = length();
+    x /= l;
+    y /= l;
+    return *this;
+}
+
+template <class T>
+Vec2<T>
+Vec2<T>::normalized () const
+{
+    T l = length();
+
+    if (l == 0)
+       return Vec2 (T (0));
+
+    return Vec2 (x / l, y / l);
+}
+
+template <class T>
+Vec2<T>
+Vec2<T>::normalizedExc () const throw (Iex::MathExc)
+{
+    T l = length();
+
+    if (l == 0)
+       throw NullVecExc ("Cannot normalize null vector.");
+
+    return Vec2 (x / l, y / l);
+}
+
+template <class T>
+inline
+Vec2<T>
+Vec2<T>::normalizedNonNull () const
+{
+    T l = length();
+    return Vec2 (x / l, y / l);
+}
+
+
+//-----------------------
+// Implementation of Vec3
+//-----------------------
+
+template <class T>
+inline T &
+Vec3<T>::operator [] (int i)
+{
+    return (&x)[i];
+}
+
+template <class T>
+inline const T &
+Vec3<T>::operator [] (int i) const
+{
+    return (&x)[i];
+}
+
+template <class T>
+inline
+Vec3<T>::Vec3 ()
+{
+    // empty
+}
+
+template <class T>
+inline
+Vec3<T>::Vec3 (T a)
+{
+    x = y = z = a;
+}
+
+template <class T>
+inline
+Vec3<T>::Vec3 (T a, T b, T c)
+{
+    x = a;
+    y = b;
+    z = c;
+}
+
+template <class T>
+inline
+Vec3<T>::Vec3 (const Vec3 &v)
+{
+    x = v.x;
+    y = v.y;
+    z = v.z;
+}
+
+template <class T>
+template <class S>
+inline
+Vec3<T>::Vec3 (const Vec3<S> &v)
+{
+    x = T (v.x);
+    y = T (v.y);
+    z = T (v.z);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator = (const Vec3 &v)
+{
+    x = v.x;
+    y = v.y;
+    z = v.z;
+    return *this;
+}
+
+template <class T>
+template <class S>
+inline void
+Vec3<T>::setValue (S a, S b, S c)
+{
+    x = T (a);
+    y = T (b);
+    z = T (c);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec3<T>::setValue (const Vec3<S> &v)
+{
+    x = T (v.x);
+    y = T (v.y);
+    z = T (v.z);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec3<T>::getValue (S &a, S &b, S &c) const
+{
+    a = S (x);
+    b = S (y);
+    c = S (z);
+}
+
+template <class T>
+template <class S>
+inline void
+Vec3<T>::getValue (Vec3<S> &v) const
+{
+    v.x = S (x);
+    v.y = S (y);
+    v.z = S (z);
+}
+
+template <class T>
+inline T *
+Vec3<T>::getValue()
+{
+    return (T *) &x;
+}
+
+template <class T>
+inline const T *
+Vec3<T>::getValue() const
+{
+    return (const T *) &x;
+}
+
+template <class T>
+template <class S>
+inline bool
+Vec3<T>::operator == (const Vec3<S> &v) const
+{
+    return x == v.x && y == v.y && z == v.z;
+}
+
+template <class T>
+template <class S>
+inline bool
+Vec3<T>::operator != (const Vec3<S> &v) const
+{
+    return x != v.x || y != v.y || z != v.z;
+}
+
+template <class T>
+bool
+Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
+{
+    for (int i = 0; i < 3; i++)
+       if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+           return false;
+
+    return true;
+}
+
+template <class T>
+bool
+Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
+{
+    for (int i = 0; i < 3; i++)
+       if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+           return false;
+
+    return true;
+}
+
+template <class T>
+inline T
+Vec3<T>::dot (const Vec3 &v) const
+{
+    return x * v.x + y * v.y + z * v.z;
+}
+
+template <class T>
+inline T
+Vec3<T>::operator ^ (const Vec3 &v) const
+{
+    return dot (v);
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::cross (const Vec3 &v) const
+{
+    return Vec3 (y * v.z - z * v.y,
+                z * v.x - x * v.z,
+                x * v.y - y * v.x);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator %= (const Vec3 &v)
+{
+    T a = y * v.z - z * v.y;
+    T b = z * v.x - x * v.z;
+    T c = x * v.y - y * v.x;
+    x = a;
+    y = b;
+    z = c;
+    return *this;
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator % (const Vec3 &v) const
+{
+    return Vec3 (y * v.z - z * v.y,
+                z * v.x - x * v.z,
+                x * v.y - y * v.x);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator += (const Vec3 &v)
+{
+    x += v.x;
+    y += v.y;
+    z += v.z;
+    return *this;
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator + (const Vec3 &v) const
+{
+    return Vec3 (x + v.x, y + v.y, z + v.z);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator -= (const Vec3 &v)
+{
+    x -= v.x;
+    y -= v.y;
+    z -= v.z;
+    return *this;
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator - (const Vec3 &v) const
+{
+    return Vec3 (x - v.x, y - v.y, z - v.z);
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator - () const
+{
+    return Vec3 (-x, -y, -z);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::negate ()
+{
+    x = -x;
+    y = -y;
+    z = -z;
+    return *this;
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator *= (const Vec3 &v)
+{
+    x *= v.x;
+    y *= v.y;
+    z *= v.z;
+    return *this;
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator *= (T a)
+{
+    x *= a;
+    y *= a;
+    z *= a;
+    return *this;
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator * (const Vec3 &v) const
+{
+    return Vec3 (x * v.x, y * v.y, z * v.z);
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator * (T a) const
+{
+    return Vec3 (x * a, y * a, z * a);
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator /= (const Vec3 &v)
+{
+    x /= v.x;
+    y /= v.y;
+    z /= v.z;
+    return *this;
+}
+
+template <class T>
+inline const Vec3<T> &
+Vec3<T>::operator /= (T a)
+{
+    x /= a;
+    y /= a;
+    z /= a;
+    return *this;
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator / (const Vec3 &v) const
+{
+    return Vec3 (x / v.x, y / v.y, z / v.z);
+}
+
+template <class T>
+inline Vec3<T>
+Vec3<T>::operator / (T a) const
+{
+    return Vec3 (x / a, y / a, z / a);
+}
+
+
+template <class T>
+inline T
+Vec3<T>::length () const
+{
+    return Math<T>::sqrt (dot (*this));
+}
+
+template <class T>
+inline T
+Vec3<T>::length2 () const
+{
+    return dot (*this);
+}
+
+template <class T>
+const Vec3<T> &
+Vec3<T>::normalize ()
+{
+    T l = length();
+
+    if (l != 0)
+    {
+       x /= l;
+       y /= l;
+       z /= l;
+    }
+
+    return *this;
+}
+
+template <class T>
+const Vec3<T> &
+Vec3<T>::normalizeExc () throw (Iex::MathExc)
+{
+    T l = length();
+
+    if (l == 0)
+       throw NullVecExc ("Cannot normalize null vector.");
+
+    x /= l;
+    y /= l;
+    z /= l;
+    return *this;
+}
+
+template <class T>
+inline
+const Vec3<T> &
+Vec3<T>::normalizeNonNull ()
+{
+    T l = length();
+    x /= l;
+    y /= l;
+    z /= l;
+    return *this;
+}
+
+template <class T>
+Vec3<T>
+Vec3<T>::normalized () const
+{
+    T l = length();
+
+    if (l == 0)
+       return Vec3 (T (0));
+
+    return Vec3 (x / l, y / l, z / l);
+}
+
+template <class T>
+Vec3<T>
+Vec3<T>::normalizedExc () const throw (Iex::MathExc)
+{
+    T l = length();
+
+    if (l == 0)
+       throw NullVecExc ("Cannot normalize null vector.");
+
+    return Vec3 (x / l, y / l, z / l);
+}
+
+template <class T>
+inline
+Vec3<T>
+Vec3<T>::normalizedNonNull () const
+{
+    T l = length();
+    return Vec3 (x / l, y / l, z / l);
+}
+
+
+//-----------------------------
+// Stream output implementation
+//-----------------------------
+
+template <class T>
+std::ostream &
+operator << (std::ostream &s, const Vec2<T> &v)
+{
+    return s << '(' << v.x << ' ' << v.y << ')';
+}
+
+template <class T>
+std::ostream &
+operator << (std::ostream &s, const Vec3<T> &v)
+{
+    return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
+}
+
+
+//-----------------------------------------
+// Implementation of reverse multiplication
+//-----------------------------------------
+
+template <class T>
+inline Vec2<T>
+operator * (T a, const Vec2<T> &v)
+{
+    return Vec2<T> (a * v.x, a * v.y);
+}
+
+template <class T>
+inline Vec3<T>
+operator * (T a, const Vec3<T> &v)
+{
+    return Vec3<T> (a * v.x, a * v.y, a * v.z);
+}
+
+
+#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
+#pragma warning(default:4290)
+#endif
+
+} // namespace Imath
+
+#endif