// MathLibrary.h: interface for the MathLibrary function.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MATHLIBRARY_H__67630672_FC1A_47C1_8FB0_BAE223336760__INCLUDED_)
#define AFX_MATHLIBRARY_H__67630672_FC1A_47C1_8FB0_BAE223336760__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <math.h>

#define	Q_PI		3.14159265358979323846264338327950288419716939937510f
#define Q_PI2		(Q_PI * 2.0f)

#define Q_PIOVER180	0.0174532925f

#define ToRadian(degree) ((degree) * (Q_PI / 180.0f))
#define ToDegree(radian) ((radian) * (180.0f / Q_PI))

// Use this definition globally
#define EPSILON			1.19e-07f		// epsilon
#define	EQUAL_EPSILON	0.001

#pragma pack(1)

/* Vector
*/
typedef struct _VECTOR2D
{
	union
	{
		float v[2];
		struct
		{
			float	x, y;
		};
	};
} VECTOR2D, *LPVECTOR2D;

typedef struct _VECTOR3D
{
	union
	{
		float	v[3];
		struct
		{
			float	x, y, z;
		};
	};
} VECTOR3D, *LPVECTOR3D;

/* Quaternions
*/
typedef struct _QUATERNION
{
	union
	{
		float	q[4];
		struct
		{
			float	x, y, z, w;
		};
	};
} QUATERNION, *LPQUATERNION;

/* Kinematics
 */
typedef struct _KINEMATICS
{
	VECTOR3D	translate;
	QUATERNION	quaternion;
} KINEMATICS, *LPKINEMATICS;
 
/* Matrices
*/
typedef struct _MATRIX
{
    union
    {
        float m[3][4];
        struct
        {
            float _00, _01, _02, _03;
            float _10, _11, _12, _13;
            float _20, _21, _22, _23;
        };
	};
} MATRIX, *LPMATRIX;
#pragma pack()

// Vector
void CopyVector(const LPVECTOR3D lpIn, LPVECTOR3D lpOut);

void AddVector(const LPVECTOR3D lpV1, const LPVECTOR3D lpV2, LPVECTOR3D lpOut);
void SubtractVector(const LPVECTOR3D lpV1, const LPVECTOR3D lpV2, LPVECTOR3D lpOut);

float NormalizeVector(LPVECTOR3D lpV);
float DotProductVector(const LPVECTOR3D lpV1, const LPVECTOR3D lpV2);

bool CompareVector(const LPVECTOR3D lpV1, const LPVECTOR3D lpV2);

// Angle
void ClipRotations(LPVECTOR3D lpV);

void AngleQuaternion(const LPVECTOR3D lpAngles, LPQUATERNION lpOut);
void AngleMatrix(const LPVECTOR3D lpAngles, LPMATRIX lpOut);
void AngleIMatrix(const LPVECTOR3D lpAngles, LPMATRIX lpOut);

void QuaternionSlerp(const LPQUATERNION lpFrom, const LPQUATERNION lpTo, float t, LPQUATERNION lpOut);
void QuaternionMatrix(const LPQUATERNION lpQ, LPMATRIX lpOut);
void MatrixQuaternion(const LPMATRIX lpM, LPQUATERNION lpOut);

// Matrix
void MatrixCopy(const LPMATRIX lpM, LPMATRIX lpOut);

void MatrixIdentity(LPMATRIX lpOut);

void MatrixTranslation(LPVECTOR3D lpV, LPMATRIX lpOut);
void MatrixScale(LPVECTOR3D lpV, LPMATRIX lpOut);

void MatrixRotateX(float angle, LPMATRIX lpOut);
void MatrixRotateY(float angle, LPMATRIX lpOut);
void MatrixRotateZ(float angle, LPMATRIX lpOut);

void MatrixMultiply(const LPMATRIX lpM1, const LPMATRIX lpM2, LPMATRIX lpOut);

void MatrixGL(const LPMATRIX lpM);


// Transform
void TransformVector(const LPVECTOR3D lpV, const LPMATRIX lpM, LPVECTOR3D lpOut);


#endif // !defined(AFX_MATHLIBRARY_H__67630672_FC1A_47C1_8FB0_BAE223336760__INCLUDED_)
