#pragma once

#include "main.h"
#include <math.h>

#define CPUID_MMX          0x00800000   //bit 23
#define CPUID_SSE          0x02000000   //bit 25
#define CPUID_3DNOW        0x80000000   //bit 31

class rMath
{
public:
	rMath();
	virtual void MatrixMultiply(float* d, float *s1, float *s2);
	virtual inline void Dot(float* d, float *s1, float *s2);
	virtual inline void MemCopy(void *d, const void *s, int Bcount);
	virtual inline float MagnitudeVA3(float *x);

	static void DetectCPU();

	static char Vendor[13];
	static int mmx;
	static int sse;
	static int _3dnow;
};

class r3DNow : public rMath
{
public:
	inline void Dot(float* d, float *s1, float *s2);
	inline void MemCopy(void *d, const void *s, int Bcount);
	inline float MagnitudeVA3(float *x);
};

rMath* InitMath();

struct vector3
{
	vector3(){};
	vector3(float X, float Y, float Z) 
	{ 
		x = X; y = Y; z = Z;
	}
	vector3 operator+(vector3 vVector)
	{
		return vector3(vVector.x + x, vVector.y + y, vVector.z + z);
	}
	vector3 operator-(vector3 vVector)
	{
		return vector3(x - vVector.x, y - vVector.y, z - vVector.z);
	}
	vector3 operator*(float m)
	{
		return vector3(x*m, y*m, z*m);
	}
	vector3 operator/(float m)
	{
		return vector3(x/m, y/m, z/m);
	}
	float x, y, z;
};

struct vector2
{
	float x,y;
};

float DotProduct ( vector3 &vVector1, vector3 &vVector2);

float Absolute(float num);
											
vector3 Cross(vector3 vVector1, vector3 vVector2);

float Magnitude(vector3 vNormal);

vector3 Normalize(vector3 vNormal);

vector3 Normal(vector3 vPolygon[]);

float Distance(vector3 vPoint1, vector3 vPoint2);
