#ifndef RIONB3_H
#define RIONB3_H

#ifndef   RIVECTOR3_H
#include <RiVector3.H>
#endif

/***************************************************************
CLASS
    RiONB3
       3D orthonormal basis class declaration

DESCRIPTION
     <Detailed description with any warnings>

****************************************************************/

class RiONB3 {
public:
				//// constructor
    RiONB3();
				////
    RiUnitVector3 U() const;
				////
    RiUnitVector3 V() const;
				////
    RiUnitVector3 W() const;

                                //// Build an ONB such that U is the arg vector
                                //   Warning: ONB is only piecewise continuous for
                                //   continuous argument.
    void BuildFromU( const RiUnitVector3& u );
                                //// Build an ONB such that V is the arg vector
                                //   Warning: ONB is only piecewise continuous for
                                //   continuous argument.
    void BuildFromV( const RiUnitVector3& v );
                                //// Build an ONB such that W is the arg vector
                                //   Warning: ONB is only piecewise continuous for
                                //   continuous argument.
    void BuildFromW( const RiUnitVector3& w );

                                //// creates ONB s.t. U = u, and W is parallel
                                // to the cross product of arguments.
    void BuildFromUV( const RiUnitVector3& u, const RiVector3& v );
                                //// creates ONB s.t. V = v, and W is parallel
                                // to the cross product of arguments.
    void BuildFromVU( const RiUnitVector3& u, const RiVector3& v );
                                //// creates ONB s.t. U = u, and V is parallel
                                // to the cross product of arguments.
    void BuildFromUW( const RiUnitVector3& u, const RiVector3& v );
                                //// creates ONB s.t. W = w, and V is parallel
                                // to the cross product of arguments.
    void BuildFromWU( const RiUnitVector3& u, const RiVector3& v );
                                //// creates ONB s.t. V = v, and U is parallel
                                // to the cross product of arguments.
    void BuildFromVW( const RiUnitVector3& u, const RiVector3& v );
                                //// creates ONB s.t. W = w, and U is parallel
                                // to the cross product of arguments.
    void BuildFromWV( const RiUnitVector3& u, const RiVector3& v );

                                //// rewrites a in terms of canonical
    RiVector3 ChangeFromBasis( const RiVector3& a ) const;
                                //// rewrites a in terms of basis
    RiVector3 ChangeToBasis( const RiVector3& a ) const;

private:
    RiUnitVector3 u0;
    RiUnitVector3 u1;
    RiUnitVector3 u2;
};

inline RiONB3::RiONB3() {}

inline  RiVector3 RiONB3::ChangeFromBasis( const RiVector3& a ) const {
    return a.X()*u0 + a.Y()*u1 + a.Z()*u2;
}

inline  RiVector3 RiONB3::ChangeToBasis( const RiVector3& a ) const {
     return RiVector3( a * u0, a * u1, a * u2 );
}



#endif /* RIONB3_H */

