/***************************************************************
 * PrTransform.h
 *
 * This class provides Transform matrix.
 *
 ****************************************************************/

/*
 * modification history
 *----------------------
 *
 * 11/20/97: K.C. Chang: added inline methods.
 * 11/06/97: K.C. Chang: created.
 */

#ifndef _PrTransform_h
#define _PrTransform_h

#include "PrGlobalDefn.h"
#include "PrVector3.h"
#include "PrQuaternion.h"
#include "PrVector6.h"
#include "PrMatrix6.h"

#define PR_MATRIX_SYMMETRIC 1

class PrTransform
{
  public:
    PrTransform() {}  // initialized to [I 0]
    PrTransform(const PrTransform &t) : rot_(t.rot_),trans_(t.trans_) {}
    PrTransform(const PrQuaternion &r,const PrVector3 &p) :rot_(r),trans_(p){}
    PrTransform(const PrQuaternion &r) : rot_(r) {}
    PrTransform(const PrVector3 &p) : trans_(p) {}
    ~PrTransform() {}

    void identity();

    PrQuaternion &rotation() { return rot_; }
    PrVector3 &translation() { return trans_; }

    PrTransform &operator=(const PrTransform &t);

    // e = T - Td
    void error(const PrTransform &Td,PrVector6 &e);

    PrTransform operator~() const;
    void inverse(PrTransform &dest) const;

    PrTransform operator*(const PrTransform &t) const;
    void multiply(const PrTransform &t,PrTransform &dest) const;

    PrVector3 operator*(const PrVector3 &v) const;
    void multiply(const PrVector3 &v,PrVector3 &dest) const;

    PrTransform &operator*=(const PrTransform &t);

    // Vi = Xt Vi-1
    // Ai = Xt Ai-1
    PrVector6 XformT(const PrVector6 &v6) const;
    void XformT(const PrVector6 &v6,PrVector6 &dest) const;

    // Fi = X Fi+1
    PrVector6 Xform(const PrVector6 &f6) const;
    void Xform(const PrVector6 &f6,PrVector6 &dest) const;

    // Mi = X Mi+1 Xt
    PrMatrix6 similarityXform(const PrMatrix6 &I,
			 int symmetric=PR_MATRIX_SYMMETRIC) const;
    void similarityXform(const PrMatrix6 &I,PrMatrix6 &dest,
			 int symmetric=PR_MATRIX_SYMMETRIC) const;


    void display(char *name=NULL);

  private:
    PrQuaternion rot_;  // rotation
    PrVector3 trans_;     // translation
};

// inline methods

inline void PrTransform::identity()
{
    rot_.identity();
    trans_.values(0.0,0.0,0.0);
}

inline PrTransform &PrTransform::operator=(const PrTransform &t)
{
    if (this != &t)
      {
	  rot_ = t.rot_;
	  trans_ = t.trans_;
      }
    return (*this);
}

#endif // _PrTransform_h

