/************************************************************************
 *									*
 *	sys_matrix.c の extern など					*
 *				1995年 12月26日(火曜日) 16時00分00秒 JST*
 ************************************************************************/
#ifndef _SYS_MATRIX_H_
#define _SYS_MATRIX_H_

#ifdef __cplusplus
extern "C" {
#endif

extern Mtx	Mtx_clear;
extern MtxF	MtxF_clear;
extern MtxF	*MtxF_now, MtxF_now_stack[];
extern MtxF	*MtxF_work, MtxF_work_stack[];

#define		SET_MTX		0	/* 行列関数用 フラグ */
#define		MULT_MTX	1	/* 行列関数用 フラグ */

/*======================================================================*
 *									*
 *	マトリックス リスト ポインター を 次 に 進める			*
 *									*
 *======================================================================*/
#define		NEXT_MTX	(Mtx_modelviewP++)

/*======================================================================*
 *									*
 *	現在 の マトリックス リスト ポインター				*
 *									*
 *======================================================================*/
#define		NOW_MTX		(Mtx_modelviewP)

/*======================================================================*
 *									*
 *	行列 の コピー							*
 *									*
 *======================================================================*/
void copy_MtxF(
    MtxF	*m0,
    MtxF	*m1
);
#define	get_now(a)	copy_MtxF(a, MtxF_now)
#define	get_work(a)	copy_MtxF(a, MtxF_work)
#define	put_now(a)	copy_MtxF(MtxF_now, a)
#define	put_work(a)	copy_MtxF(MtxF_work, a)

/*======================================================================*
 *									*
 *	表示行列 の プッシュ						*
 *									*
 *======================================================================*/
void _sys_push(
    MtxF	**
);
#define	push_now()	_sys_push(&MtxF_now)
#define	push_work()	_sys_push(&MtxF_work)

/*======================================================================*
 *									*
 *	表示行列 の プル						*
 *									*
 *======================================================================*/
void _sys_pull(
    MtxF	**
);
#define	pull_now()	_sys_pull(&MtxF_now)
#define	pull_work()	_sys_pull(&MtxF_work)

/*======================================================================*
 *									*
 *	行列 の 乗算							*
 *									*
 *======================================================================*/
void _sys_mult(
    MtxF	*,	/* 掛けられる 行列 */
    MtxF	*,	/* 掛ける 行列 */
    char		/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	mult_now(a, b)	_sys_mult(MtxF_now, (a), (b))
#define	mult_work(a, b)	_sys_mult(MtxF_work, (a), (b))
#define	mult_now_work()	mult_now(MtxF_work, MULT_MTX)

/*======================================================================*
 *									*
 *	トランスレート行列						*
 *									*
 *======================================================================*/
void _sys_translate(
    MtxF	*,
    float,	/* Ｘ 角度 */
    float,	/* Ｙ 角度 */
    float,	/* Ｚ 角度 */
    char	/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	translate_now(a, b, c, d) \
	_sys_translate(MtxF_now, (a), (b), (c), (d))
#define	translate_work(a, b, c, d) \
	_sys_translate(MtxF_work, (a), (b), (c), (d))
/*======================================================================*
 *									*
 *	スケール行列							*
 *									*
 *======================================================================*/
void _sys_scale(
    MtxF	*,
    float,	/* Ｘ 倍率 */
    float,	/* Ｙ 倍率 */
    float,	/* Ｚ 倍率 */
    char	/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	scale_now(a, b, c, d)	_sys_scale(MtxF_now, (a), (b), (c), (d))
#define	scale_work(a, b, c, d)	_sys_scale(MtxF_work, (a), (b), (c), (d))
/*======================================================================*
 *									*
 *	Ｘローテート行列						*
 *									*
 *======================================================================*/
void _sys_rotateX(
    MtxF	*,
    float,	/* 角度 */
    char	/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	rotateX_now(a, b)	_sys_rotateX(MtxF_now, (a), (b))
#define	rotateX_work(a, b)	_sys_rotateX(MtxF_work, (a), (b))
/*======================================================================*
 *									*
 *	Ｙローテート行列						*
 *									*
 *======================================================================*/
void _sys_rotateY(
    MtxF	*,
    float,	/* 角度 */
    char	/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	rotateY_now(a, b)	_sys_rotateY(MtxF_now, (a), (b))
#define	rotateY_work(a, b)	_sys_rotateY(MtxF_work, (a), (b))
/*======================================================================*
 *									*
 *	Ｚローテート行列						*
 *									*
 *======================================================================*/
void _sys_rotateZ(
    MtxF	*,
    float,	/* 角度 */
    char	/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	rotateZ_now(a, b)	_sys_rotateZ(MtxF_now, (a), (b))
#define	rotateZ_work(a, b)	_sys_rotateZ(MtxF_work, (a), (b))
/*======================================================================*
 *									*
 *	指定軸による ローテート						*
 *									*
 *======================================================================*/
void _sys_rotate(
    MtxF	*,
    float	,	/* 角度 */
    float	,
    float	,
    float	,
    char		/* SET_MTX:行列 の ロード  MULT_MTX:行列 の 乗算 */
);
#define	rotate_now(a, b, c, d, e) \
	_sys_rotate(MtxF_now, (a), (b), (c), (d), (e))
#define	rotate_work(a, b, c, d, e) \
	_sys_rotate(MtxF_work, (a), (b), (c), (d), (e))
/*======================================================================*
 *									*
 *	MtxF --> Mtx							*
 *									*
 *======================================================================*/
#if 0 < FOX_DEBUG
void nowtoMtx0(
    Mtx		*
);
void nowtoMtx1(
    Mtx		*
);
void nowtoMtx2(
    Mtx		*
);
void nowtoMtx3(
    Mtx		*
);
void nowtoMtx4(
    Mtx		*
);
void nowtoMtx5(
    Mtx		*
);
void nowtoMtx6(
    Mtx		*
);
void nowtoMtx7(
    Mtx		*
);
void nowtoMtx8(
    Mtx		*
);
void nowtoMtx9(
    Mtx		*
);
#define		nowtoMtx	nowtoMtx0
#else
void nowtoMtx(
    Mtx		*
);
#define		nowtoMtx0	nowtoMtx
#define		nowtoMtx1	nowtoMtx
#define		nowtoMtx2	nowtoMtx
#define		nowtoMtx3	nowtoMtx
#define		nowtoMtx4	nowtoMtx
#define		nowtoMtx5	nowtoMtx
#define		nowtoMtx6	nowtoMtx
#define		nowtoMtx7	nowtoMtx
#define		nowtoMtx8	nowtoMtx
#define		nowtoMtx9	nowtoMtx
#endif

/*======================================================================*
 *									*
 *	Mtx --> MtxF							*
 *									*
 *======================================================================*/
void MtxtoMtxF(
    Mtx		*,
    MtxF	*
);
/*======================================================================*
 *									*
 *	座標 の 計算							*
 *									*
 *======================================================================*/
/*----------------------------------------------------------------------*
 *	トランスレート ローテート スケール を 含む			*
 *----------------------------------------------------------------------*/
void _sys_MtxF_PositionTRS(
    MtxF	*,
    xyz_t	*,
    xyz_t	*
);
#define	MtxF_Position_now(a, b)	 _sys_MtxF_PositionTRS(MtxF_now, (a), (b))
#define	MtxF_Position_work(a, b) _sys_MtxF_PositionTRS(MtxF_work, (a), (b))
//#define	MtxF_Position2		 MtxF_Position_now
/*----------------------------------------------------------------------*
 *	ローテート スケール を 含む					*
 *----------------------------------------------------------------------*/
void _sys_MtxF_PositionRS(
    MtxF	*,
    xyz_t	*,
    xyz_t	*
);
#define	MtxF_PositionRS_now(a, b)  _sys_MtxF_PositionRS(MtxF_now, (a), (b))
#define	MtxF_PositionRS_work(a, b) _sys_MtxF_PositionRS(MtxF_work, (a), (b))

/*======================================================================*
 *									*
 *	行列から角度を求める						*
 *									*
 *======================================================================*/
void _sys_MtxF_AngleYXZ(
    MtxF	*,
    xyz_t	*
);
void _sys_MtxF_AngleZYX(
    MtxF	*,
    xyz_t	*
);
#define	MtxF_AngleYXZ_now(a)  _sys_MtxF_AngleYXZ(MtxF_now, (a))
#define	MtxF_AngleYXZ_work(a)  _sys_MtxF_AngleYXZ(MtxF_work, (a))
#define	MtxF_AngleZYX_now(a)  _sys_MtxF_AngleZYX(MtxF_now, (a))
#define	MtxF_AngleZYX_work(a)  _sys_MtxF_AngleZYX(MtxF_work, (a))
#define	MtxF_Angle_now	MtxF_AngleYXZ_now
#define	MtxF_Angle_work	MtxF_AngleYXZ_work

/*======================================================================*
 *									*
 *	guLookAt を 行列 に セットする					*
 *									*
 *======================================================================*/
void _set_lookat(
    MtxF	*,
    float	,
    float	,
    float	,
    float	,
    float	,
    float	,
    float	,
    float	,
    float	,
    char	
);
#define	set_lookat_now(a, b, c, d, e, f, g, h, i, j) \
    _set_lookat(MtxF_now, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j))
#define	set_lookat_work(a, b, c, d, e, f, g, h, i, j) \
    _set_lookat(MtxF_work, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j))

/*======================================================================*
 *									*
 *	現在の行列をディスプレイリストにセットする			*
 *									*
 *======================================================================*/
#if 0 < FOX_DEBUG
void set_matrix0(
    Gfx		**
);
void set_matrix1(
    Gfx		**
);
void set_matrix2(
    Gfx		**
);
void set_matrix3(
    Gfx		**
);
void set_matrix4(
    Gfx		**
);
void set_matrix5(
    Gfx		**
);
void set_matrix6(
    Gfx		**
);
void set_matrix7(
    Gfx		**
);
void set_matrix8(
    Gfx		**
);
void set_matrix9(
    Gfx		**
);
#define		set_matrix		set_matrix0
#else
void set_matrix(
    Gfx		**
);
#define		set_matrix0		set_matrix
#define		set_matrix1		set_matrix
#define		set_matrix2		set_matrix
#define		set_matrix3		set_matrix
#define		set_matrix4		set_matrix
#define		set_matrix5		set_matrix
#define		set_matrix6		set_matrix
#define		set_matrix7		set_matrix
#define		set_matrix8		set_matrix
#define		set_matrix9		set_matrix

#endif




#ifdef __cplusplus
}
#endif

#endif	/* _SYS_MATRIX_H_ */
