#ifndef V_SPACE_H
#define V_SPACE_H

/*	Plane equation is n[0]*x + n[1]*y + n[2]*z - dist = 0 */
typedef struct	plane3_s
{
	vec3_t  normal;
	/*	distance positive if normal directed to the origin */
	vec_t   dist;
}	plane3_t, *plane3_p;

/*	line in space defined parametric */
typedef struct	line3_s
{
  vec3_t origin;	/*	any point on line */
  vec3_t dir;	/*	direction of line */
}	line3_t, *line3_p;

/*	Possible directions of line */
typedef enum
{
  dir_x = 1,
  dir_y = 2,
  dir_z = 3,
  dir_anyx = 4,
  dir_anyy = 5,
  dir_anyz = 6
} vecdir_t;

#ifdef	__cplusplus
extern "C" {
#endif	/* __cplusplus */
	void		V_GLOBAL	mat3Scale(matrix3_t m,vec3_t scale);
	void		V_GLOBAL	mat3RotateX(matrix3_t mat,vec_t radians);
	void		V_GLOBAL	mat3RotateY(matrix3_t mat,vec_t radians);
	void		V_GLOBAL	mat3RotateZ(matrix3_t mat,vec_t radians);
	void		V_GLOBAL	mat3Rotate(matrix3_t mat,vec3_t dir,
								vec_t radians);
	void		V_GLOBAL	mat3FromDirAndUp(matrix3_t mat,vec3_t dir,
								vec3_t up);

	void		V_GLOBAL	mat3x4Scale(matrix3x4_t m,vec3_t scale);
	void		V_GLOBAL	mat3x4Translate(matrix3x4_t m,vec3_t t);
	void		V_GLOBAL	mat3x4RotateX(matrix3x4_t mat,vec_t radians);
	void		V_GLOBAL	mat3x4RotateY(matrix3x4_t mat,vec_t radians);
	void		V_GLOBAL	mat3x4RotateZ(matrix3x4_t mat,vec_t radians);
	void		V_GLOBAL	mat3x4Rotate(matrix3x4_t mat,vec3_t dir,
								vec_t radians);
	void		V_GLOBAL	mat3x4FromDirAndUp(matrix3x4_t mat,vec3_t dir,
								vec3_t up);
	void		V_GLOBAL	mat3x4FromPointDirAndUp(matrix3x4_t mat,
								vec3_t pt,vec3_t dir,vec3_t up);

	void		V_GLOBAL	vec3Perpendicular(vec3_t dest,vec3_t v);
	void		V_GLOBAL	vec3RotateAround(vec3_t dst,vec3_t dir,
								vec3_t point,vec_t radians);
	void		V_GLOBAL	vec3ProjectOnPlane(vec3_t dest,vec3_t pt,
								plane3_t *plane);
	void		V_GLOBAL	vec3FromLineAndPlane(vec3_t dest,line3_p line,
								plane3_p plane);
	void		V_GLOBAL	vec3PlaneReflection(vec3_t dest,plane3_p pl,
								vec3_t src);

	void		V_GLOBAL	line3FromPoints(line3_p dest,vec3_t p1,
								vec3_t p2);
	void		V_GLOBAL	line3FromDirAndOrigin(line3_t *line,
								vec3_t dir,vec3_t origin);

	void		V_GLOBAL	plane3FromPoints(plane3_p dest,vec3_t a,
								vec3_t b,vec3_t c);
	void		V_GLOBAL	plane3FromLines(plane3_p dest,line3_p l1,
								line3_p l2);

	void		V_GLOBAL	bboxClear(vec3_t mins,vec3_t maxs);
	void		V_GLOBAL	bboxAddPoint(vec3_t mins,vec3_t maxs,
								vec3_t p);
	void		V_GLOBAL	bboxTransformFromBoxes(matrix3x4_t dest,
		vec3_t in_mins,vec3_t in_maxs,vec3_t out_mins,vec3_t out_maxs);
#ifdef	__cplusplus
}
#endif	/* __cplusplus */

#endif	/* V_SPACE_H */
