// ### OpenGTA3 ###
// math primitives (matrix, sphere, rect, quaternion, ...)

#pragma pack(push,1)

int	random(int l, int h);	// returns random number in range l..h-1
//=============================================================================
// renderware structures
struct RwMatrix {
	D3DVECTOR	right;
	DWORD		flags;
	D3DVECTOR	top;
	DWORD		_pad1;
	D3DVECTOR	at;
	DWORD		_pad2;
	D3DVECTOR	pos;
	DWORD		_pad3;

	void makeIdentityMatrix (float value = 1.0f);
};

struct RwSphere {
    D3DVECTOR	center; 
    float		radius; 

	void init (float _radius, D3DVECTOR * _center);	// >> 40FCF0 (25)
};

struct RtQuat {
	D3DVECTOR	imag;
	float		real;
};

struct RwBBox {
	D3DVECTOR	sup;
	D3DVECTOR	inf;

	RwBBox () {}
	RwBBox (RwSphere * sphere);
};


// vectors
float dotProduct (D3DVECTOR * v1, D3DVECTOR * v2);	// >> 40FDB0 (55)
D3DVECTOR * crossProduct (D3DVECTOR * out, D3DVECTOR * a, D3DVECTOR * b); // >> 59C730 (210)
D3DVECTOR * vectorAdd (D3DVECTOR * out, D3DVECTOR * in1, D3DVECTOR * in2); // >> 40FE30 (99)	TODO: make operator
D3DVECTOR * vectorAddF (D3DVECTOR * out, D3DVECTOR * in1, float in2);
D3DVECTOR * vectorSub (D3DVECTOR * out, D3DVECTOR * in1, D3DVECTOR * in2); // >> 40FE60 (257)	TODO: make operator
D3DVECTOR * vectorSubF (D3DVECTOR * out, D3DVECTOR * in1, float in2);

inline float vectorLengthSq (D3DVECTOR * v) { return v->x*v->x+v->y*v->y+v->z*v->z; } 

// matrices
RwMatrix * RwMatrixUpdate (RwMatrix * m);	// >> 7F18A0 (37)

// OO-wrapper around RwMatrix
// NOTE: по мере переноса, следует переходить к использованию D3DMATRIX (и, возможно, унаследоваться от нее)
struct CMatrix {
	RwMatrix	m;		// 
	RwMatrix *	rwm;	// pointer to RwMatrix
	DWORD		ownMatrix;	// флаг, выставляемый, если RW Matrix выделена и проинициализирована

	CMatrix () { rwm = NULL; ownMatrix = 0; }
	~CMatrix ();	// >> 59ACD0 (471)

	void attach (RwMatrix * matrix, BYTE own);	// >> 59BD10 (64);

	RwMatrix * copyTo (RwMatrix * target);	// >> 59AD70 (57)
	void fullCopyFrom (RwMatrix * src); // >> 59ADD0 (1)	TODO: inline it ?
	void setPos (float x, float y, float z);	// 59AF80 (11)

	void setIdentityMatrix ();	// >> 59AE70 (20)
};

extern void transformPoint (D3DVECTOR * dst, CMatrix * m, D3DVECTOR * point);

// OO-wrapper around RtQuat
// TODO: использовать вместо RtQuat, где возможно
struct CQuaternion : public RtQuat {
	void	get (RwMatrix * m);
};

// 2D rectangle
struct CRect {
	float	l;	// left 
	float	t;	// top
	float	r;	// roght
	float	b;	// bottom

	CRect () {}
	CRect (float _l, float _t, float _r, float _b) : l(_l), t(_t), r(_r), b(_b) {}
	void includePoint (float x, float y);	// убедиться, что точка находится внутри прямоугольника. расширить прямоугольник при необходимости

};

struct V2D	{
	float x;
	float y;
};
#pragma pack(pop)