DUMB3D.H

/************************************************************************** 
dumb3d.h - A simple linear algebra library for 3D.

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

(C) Copyright 1995-1996 Microsoft Corp. All rights reserved.

You have a royalty-free right to use, modify, reproduce and
distribute the Sample Files (and/or any modified version) in
any way you find useful, provided that you agree that
Microsoft has no warranty obligations or liability for any
Sample Application Files which are modified.

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

#if !defined(DUMB3D_HPP)
#define DUMB3D_HPP

/*----------------------------------------------------------------------------

This header contains the declarations for the dumb3d functions.

*/


// real type

typedef double real;


#define M_PI 3.14159265358979323846


// forward declarations

class point_4;
class vector_4;
class matrix_4x4;

/*----------------------------------------------------------------------------

globally useful functions.

*/

inline vector_4 operator-( point_4 const &Operand1, point_4 const &Operand2 );

inline vector_4 operator+( vector_4 const &Operand1,
vector_4 const &Operand2 );

inline vector_4 operator-( vector_4 const &Operand1,
vector_4 const &Operand2 );

inline vector_4 operator*( vector_4 const &Multiplicand,
real const &Multiplier );

inline vector_4 operator*( real const &Multiplier,
vector_4 const &Multiplicand );

inline point_4 operator+( point_4 const &Operand1, vector_4 const &Operand2 );
inline point_4 operator-( point_4 const &Operand1, vector_4 const &Operand2 );
inline point_4 operator+( vector_4 const &Operand2, point_4 const &Operand1 );

inline vector_4 operator-( vector_4 const &Operand1 );

inline vector_4 CrossProduct( vector_4 const &Operand1,
vector_4 const &Operand2 );

inline real DotProduct( vector_4 const &Operand1, vector_4 const &Operand2 );

matrix_4x4 operator*( matrix_4x4 const &Multiplicand,
matrix_4x4 const &Multiplier );

vector_4 operator*( matrix_4x4 const &Multiplicand,
vector_4 const &Multiplier );

point_4 operator*( matrix_4x4 const &Multiplicand,
point_4 const &Multiplier );




/*----------------------------------------------------------------------------

quadruple. Base class for homogeneous vectors and points.

*/

class quadruple
{
public:

inline real GetElement( int Row ) const;

inline real GetX( void ) const;
inline real GetY( void ) const;
inline real GetZ( void ) const;
inline real GetW( void ) const;

inline void SetElement( int Row, real Value );

inline void SetX( real Value );
inline void SetY( real Value );
inline void SetZ( real Value );
inline void SetW( real Value );


protected:

inline quadruple( void );
inline quadruple( real X, real Y, real Z, real W );
inline quadruple( quadruple const & );
inline quadruple &operator=( quadruple const & );

real aElements[4];
};


/*----------------------------------------------------------------------------

point_4. This class represents a homogeneous 3D point.

*/

class point_4 :
public quadruple
{
public:

inline point_4( void );
inline point_4( real X, real Y, real Z );

inline void Homogenize( void );
};

/*----------------------------------------------------------------------------

vector_4. This class represents a homogeneous 3D vector.

*/

class vector_4 :
public quadruple
{
public:

inline vector_4( void );
inline vector_4( real X, real Y, real Z );

vector_4 &Normalize( void );
};



/*----------------------------------------------------------------------------

matrix_4x4. This class represents row major 4x4 homogeneous matrices.

*/

class matrix_4x4
{
public:

matrix_4x4( void );

matrix_4x4 &ConcatenateXRotation( real Degrees );
matrix_4x4 &ConcatenateYRotation( real Degrees );
matrix_4x4 &ConcatenateZRotation( real Degrees );

matrix_4x4 &ConcatenateXTranslation( real Distance );
matrix_4x4 &ConcatenateYTranslation( real Distance );
matrix_4x4 &ConcatenateZTranslation( real Distance );

inline real GetElement( int Row, int Column ) const;
inline matrix_4x4 &SetElement( int Row, int Column, real Value );
inline matrix_4x4 & operator=(matrix_4x4 const & m);

protected:

enum do_not_initialize { DoNotInitialize };

inline matrix_4x4( do_not_initialize );

real aElements[4][4];
};

/*----------------------------------------------------------------------------

view transform.

*/

class view_transform :
public matrix_4x4
{
public:

view_transform( point_4 const &Viewpoint, vector_4 const &ViewDirection,
vector_4 const &Up );
};


/*----------------------------------------------------------------------------

inline function definitions.

*/


inline vector_4 operator-( point_4 const &Operand1, point_4 const &Operand2 )
{
return vector_4(Operand1.GetX() - Operand2.GetX(),
Operand1.GetY() - Operand2.GetY(),
Operand1.GetZ() - Operand2.GetZ());
}

inline vector_4 operator+( vector_4 const &Operand1,
vector_4 const &Operand2 )
{
return vector_4(Operand1.GetX() + Operand2.GetX(),
Operand1.GetY() + Operand2.GetY(),
Operand1.GetZ() + Operand2.GetZ());
}

inline vector_4 operator-( vector_4 const &Operand1,
vector_4 const &Operand2 )
{
return vector_4(Operand1.GetX() - Operand2.GetX(),
Operand1.GetY() - Operand2.GetY(),
Operand1.GetZ() - Operand2.GetZ());
}

inline vector_4 operator-( vector_4 const &Operand1 )
{
return vector_4(-Operand1.GetX(),-Operand1.GetY(),-Operand1.GetZ());
}

inline vector_4 operator*( vector_4 const &Multiplicand,
real const &Multiplier )
{
return vector_4(Multiplicand.GetX() * Multiplier,
Multiplicand.GetY() * Multiplier,
Multiplicand.GetZ() * Multiplier);
}

inline vector_4 operator*( real const &Multiplier,
vector_4 const &Multiplicand )
{
return vector_4(Multiplicand.GetX() * Multiplier,
Multiplicand.GetY() * Multiplier,
Multiplicand.GetZ() * Multiplier);
}

inline point_4 operator+( point_4 const &Operand1, vector_4 const &Operand2 )
{
return point_4(Operand1.GetX() + Operand2.GetX(),
Operand1.GetY() + Operand2.GetY(),
Operand1.GetZ() + Operand2.GetZ());
}

inline point_4 operator-( point_4 const &Operand1, vector_4 const &Operand2 )
{
return point_4(Operand1.GetX() - Operand2.GetX(),
Operand1.GetY() - Operand2.GetY(),
Operand1.GetZ() - Operand2.GetZ());
}

inline point_4 operator+( vector_4 const &Operand1, point_4 const &Operand2 )
{
return Operand2 + Operand1;
}

inline vector_4 CrossProduct( vector_4 const &Operand1,
vector_4 const &Operand2 )
{
real X = Operand1.GetY() * Operand2.GetZ() -
Operand1.GetZ() * Operand2.GetY();
real Y = Operand1.GetZ() * Operand2.GetX() -
Operand1.GetX() * Operand2.GetZ();
real Z = Operand1.GetX() * Operand2.GetY() -
Operand1.GetY() * Operand2.GetX();

return vector_4(X,Y,Z);
}

inline real DotProduct( vector_4 const &Operand1, vector_4 const &Operand2 )
{
return Operand1.GetX() * Operand2.GetX() +
Operand1.GetY() * Operand2.GetY() +
Operand1.GetZ() * Operand2.GetZ();
}


inline real quadruple::GetElement( int Row ) const
{
return aElements[Row];
}

inline real quadruple::GetX( void ) const
{
return aElements[0];
}

inline real quadruple::GetY( void ) const
{
return aElements[1];
}

inline real quadruple::GetZ( void ) const
{
return aElements[2];
}

inline real quadruple::GetW( void ) const
{
return aElements[3];
}

inline void quadruple::SetElement( int Row, real Value )
{
aElements[Row] = Value;
}

inline void quadruple::SetX( real Value )
{
aElements[0] = Value;
}

inline void quadruple::SetY( real Value )
{
aElements[1] = Value;
}

inline void quadruple::SetZ( real Value )
{
aElements[2] = Value;
}

inline void quadruple::SetW( real Value )
{
aElements[3] = Value;
}

inline void point_4::Homogenize( void )
{
aElements[0] = aElements[0] / aElements[3];
aElements[1] = aElements[1] / aElements[3];
aElements[2] = aElements[2] / aElements[3];
}

inline quadruple::quadruple( void )
{
aElements[0] = aElements[1] = aElements[2] = aElements[3] = 0;
}

inline quadruple::quadruple( real X, real Y, real Z, real W )
{
aElements[0] = X;
aElements[1] = Y;
aElements[2] = Z;
aElements[3] = W;
}

inline quadruple::quadruple( quadruple const &Source )
{
aElements[0] = Source.aElements[0];
aElements[1] = Source.aElements[1];
aElements[2] = Source.aElements[2];
aElements[3] = Source.aElements[3];
}

inline quadruple &quadruple::operator=( quadruple const &Source )
{
aElements[0] = Source.aElements[0];
aElements[1] = Source.aElements[1];
aElements[2] = Source.aElements[2];
aElements[3] = Source.aElements[3];

return *this;
}

inline point_4::point_4( void ) :
quadruple(0,0,0,1)
{

}

inline point_4::point_4( real X, real Y, real Z ) :
quadruple(X,Y,Z,1)
{
#if 0
char aBuffer[100];
sprintf(aBuffer,"X: %f Y: %f Z: %f",X,Y,Z);
MessageBox(0,aBuffer,"foobar",MB_OK);
sprintf(aBuffer,"X: %f Y: %f Z: %f W:%f",aElements[0],aElements[1],
aElements[2],aElements[3]);
MessageBox(0,aBuffer,"foobar",MB_OK);
#endif
}

inline vector_4::vector_4( void ) :
quadruple(0,0,0,0)
{

}

inline vector_4::vector_4( real X, real Y, real Z ) :
quadruple(X,Y,Z,0)
{

}

inline real matrix_4x4::GetElement( int Row, int Column ) const
{
return aElements[Row][Column];
}

inline matrix_4x4 &matrix_4x4::SetElement( int Row, int Column, real Value )
{
aElements[Row][Column] = Value;

return *this;
}

inline matrix_4x4::matrix_4x4( do_not_initialize )
{

}

inline matrix_4x4 & matrix_4x4::operator=(matrix_4x4 const & m)
{
memcpy((void *) aElements, (void *) m.aElements,sizeof(aElements));
return *this;
}
#endif