// ===================================================================
// $Id: matrix3.h,v 1.2 2002/11/25 20:31:12 havran Exp $
//
// matrix3.h
//	Header file for CMatrix3 class.
//
// Class: CMatrix3
//
// Licence and usage conditions in November 2003:
// This file can be used and modified only with written permission of
// Vlastimil Havran, Pohodli 27, 57001 Litomysl, the Czech Republic.
// This library is granted to be used by Polina Kondratieva within
// her MPI HIWI job working on BRDFLIB library. The usage condition
// may change in the next version of the library. At the moment,
// the library development is supported by Max-Planck-Institut for
// Informatik, Stuhlsatzenhausweg 85, 66123 Saarbruecken Germany
// See WWW: http://www.mpi-sb.mpg.de
// REPLACEMENT_STRING
//
// Initial coding by Vlastimil Havran, using matrix4.h, 2000.
//
// Given to BRDFLIB project for the Polina Kondratieva's
// HIWI JOB assignment in November 2003.
// ===================================================================


#ifndef __MATRIX3_H__
#define __MATRIX3_H__

// BRDFLIB headers
#include "configh.h"

__BEGIN_BRDFLIB_HEADER

// Forward declarations
class CVector2D;
class CVector3D;
class CVector4D;
class CMatrix4;

class CMatrix3
{
public:
  float x[3][3]; // first index is column [x], the second is row [y]

  CMatrix3() { }
  CMatrix3(float x11, float x12, float x13,
	   float x21, float x22, float x23,
	   float x31, float x32, float x33);

  // copy submatrix from the 4x4 matrix
  CMatrix3(const CMatrix4 &src);

  // Assignment operators
  CMatrix3& operator+= (const CMatrix3 &A); 	 // add-to
  CMatrix3& operator-= (const CMatrix3 &A); 	 // subtract-from
  CMatrix3& operator*= (const CMatrix3 &A); 	 // multiply by matrix
  CMatrix3& operator*= (float A); 		 // scale by scalar

  // Fundamental operations
  int Invert();	      		// Invert the matrix .. returns 0 = regular
  void Transpose();				 // Transpose the matrix
  friend CMatrix3 Invert(const CMatrix3 &M);     // Invert a given matrix
  friend CMatrix3 Transpose(const CMatrix3 &M);  // Transpose a given matrix

  // Create various types of matrix.
  friend CMatrix3 IdentityMatrix3();
  friend CMatrix3 ZeroMatrix3();
  friend CMatrix3 TranslationMatrix3(const CVector2D &Location);
  friend CMatrix3 RotationMatrix3(float Angle);
  friend CMatrix3 ScaleMatrix3(float X, float Y);
  friend CMatrix3 RotationMatrix3(const CVector3D &dir1,
				  const CVector3D &dir2);
  
  friend CMatrix3 MirrorX2D();
  friend CMatrix3 MirrorY2D();

  // Binary operators
  friend CMatrix3 operator+ (const CMatrix3 &A, const CMatrix3 &B);
  friend CMatrix3 operator- (const CMatrix3 &A, const CMatrix3 &B);
  friend CMatrix3 operator* (const CMatrix3 &A, float B);
  friend CMatrix3 operator* (const CMatrix3 &A, const CMatrix3 &B);

  // friends returning CVector2D
  friend CVector2D operator*(const CMatrix3 &M, const CVector2D &v);

  // Construct rotation description according VRML'97 specification
  const CVector4D SFRotation(void) const;

  friend CMatrix3 GenRotation3(const CVector3D &x, const CVector3D &y,
			       const CVector3D &z);
  
  // Overloaded output operator.
  friend ostream& operator<< (ostream &s, const CMatrix3 &M);
};


__END_BRDFLIB_HEADER

#endif // __MATRIX3_H__

