/*
	Ninja Library
	
	COPYRIGHT (C) SEGA ENTERPRISES,LTD.

*/
#ifndef _NU_MOTION_DEV_H_
#define	_NU_MOTION_DEV_H_


#define	NUD_MTYPE_SLOT_MAX		11

typedef	void	NUF_MOTION_INT_F3_FUNC( const NUS_MKEY_F *key, Uint32 nbkeys, Float frame, Float *dst );
typedef	void	NUF_MOTION_INT_A3_FUNC( const NUS_MKEY_A *key, Uint32 nbkeys, Float frame, Angle *dst );
typedef	void	NUF_MOTION_INT_A1_FUNC( const NUS_MKEY_A1 *key, Uint32 nbkeys, Float frame, Angle *dst );
typedef	void	NUF_MOTION_INT_SA3_FUNC( const NUS_MKEY_SA *key, Uint32 nbkeys, Float frame, Sangle *dst );


extern NUF_MOTION_INT_F3_FUNC		*_nu_motion_int_f3_func_table_[2];
extern NUF_MOTION_INT_A3_FUNC		*_nu_motion_int_a3_func_table_[2];
extern NUF_MOTION_INT_A1_FUNC		*_nu_motion_int_a1_func_table_[2];
extern NUF_MOTION_INT_SA3_FUNC		*_nu_motion_int_sa3_func_table_[2];


/*
	モーション共通データ構造体
	
	モーション描画関数
	モーション取得関数
	カメラモーション関数
	カメラモーション取得関数
	モーションリンク関数
	モーションリンク取得関数
	
	で使用される。
*/
typedef struct {
	void		*mdata;					/* NUS_MDATA(n) structure */
	int			mdata_nbkeys_ofs;		/* nbkeys offset from NUS_MDATA(n) structure top	*/
	int			mdata_size;				/* sizeof NUS_MDATA(n) structure			*/
	void		**key;					/* Motion's pointer (mdata->p) */
	Uint32		*nbkeys;				/* array of the number of keyframes（mdata->nb） */
	Float		frame;					/* current frame */
	Uint32		nbframes;				/* total number of keyframes */
	Uint32		cnt;					/* array index for NUS_MDATA(n)'s members */
	Uint32		type;
	
	NUF_MOTION_INT_F3_FUNC	*int_f3_func_p;		/*	Float * 3	補完関数	*/
	NUF_MOTION_INT_A3_FUNC	*int_a3_func_p;		/*	Angle * 3	補完関数	*/
	NUF_MOTION_INT_A1_FUNC	*int_a1_func_p;		/*	Angle * 1	補完関数	*/
	NUF_MOTION_INT_SA3_FUNC	*int_sa3_func_p;	/*	Sangle * 3	補完関数	*/
	
	//	オブジェクト系モーション関数で使用されるメンバ
	int			(*get_pos_func_p)( Float pos[3] );
	int			(*get_ang_func_p)( Angle ang[3] );
	int			(*get_scl_func_p)( Float scl[3] );
	int			(*get_qua_func_p)( NJS_QUATERNION *qua );
	int			(*get_sang_func_p)( Sangle ang[3] );
	
	//Uint32		slot_loc[NUD_MTYPE_SLOT_MAX];
} NUS_CUR_MOTION_INFO;

/*
	シェープデータ構造体
	
	シェープ描画関数
	シェープ取得関数
	で使用される。
	
	
	シェープリンク関数
	シェープリンク取得関数
	
	で使用される予定。
*/
#if 0
typedef struct {
	void		*mdata;					/* NUS_MDATA(n) structure */
	int			mdata_nbkeys_ofs;		/* nbkeys offset from NUS_MDATA(n) structure top	*/
	int			mdata_size;				/* sizeof NUS_MDATA(n) structure			*/
	void		**key;					/* Motion's pointer (mdata->p) */
	Uint32		*nbkeys;				/* array of the number of keyframes（mdata->nb） */
	Float		frame;					/* current frame */
	Uint32		nbframes;				/* total number of keyframes */
	Uint32		cnt;					/* array index for NUS_MDATA(n)'s members */
	Uint32		type;
	
	//void	(*int_vlist_func_p)( NUS_MKEY_P *key, Uint32 keyno, Uint32 n, Sint32 **vlist );		//	vlist 補完関数
} NUS_CUR_SHAPE_INFO;
#else
typedef struct {
	NUS_MDATA1		*mdata;					/* NUS_MDATA(n) structure */
	Float			frame;					/* current frame */
	Uint32			nbframes;				/* total number of keyframes */
	Uint32			cnt;					/* current node chunk numbers */
	NUS_CSHAPEDATA	*group;					/* current key frame group */
	Uint32			checkID;				/*							*/
	Uint32			KeyGroupID;				/* key group id				*/
} NUS_CUR_SHAPE_INFO;
#endif

/*
	シェープキーグループ補間構造体
	
	キーグループの補間係数を格納する
	キーグループ単位で係数が決まるので
	毎回すべてのノードで計算する必要はない
*/
typedef struct {
	Uint32		checkID;				/* リファレンスカウンタチェック用ID	*/
	Uint32		ShapeID1,ShapeID2;		/* 補間する２つのシェープID			*/
	Float		rate;					/* 補間係数							*/
} NUS_SHAPE_GROUP_COEFF;

/*
	オブジェクトモーションデータ構造体
	
	モーション描画関数
	モーション取得関数
	モーションリンク描画関数
	シェープ描画関数
	
	で使用される。
*/
typedef struct {
	Float		*pos_buf_ptr;			/*	_nu_mot_pos_buf_ptr_	*/
	Float		*scl_buf_ptr;			/*	_nu_mot_scl_buf_ptr_	*/
	Angle		*ang_buf_ptr;			/*	_nu_mot_ang_buf_ptr_	*/
	
	Sint32		(*draw_func_p)( NJS_CNK_MODEL *cnkmdl );
} NUS_CUR_OBJMOTION_INFO;


typedef struct {
	Float		rate;					/* interpolation rate between motion0 and motion1 */
} NUS_CUR_MOTIONLINK_INFO;

/*
	external defined global variables declarations
*/
#define	NUD_MOTION_INFO_MAX		2										/*	モーション構造体のスロット数		*/
extern NUS_CUR_MOTION_INFO		_nu_motion_info_[NUD_MOTION_INFO_MAX];	/*	モーション構造体					*/
extern NUS_CUR_MOTION_INFO		*_nu_motinfo_ptr_;						/*	カレントモーション構造体へのポインタ*/

#define	NUD_SHAPE_INFO_MAX		2										/*	シェープ構造体のスロット数			*/
extern NUS_CUR_SHAPE_INFO		_nu_shape_info_[NUD_SHAPE_INFO_MAX];	/*	シェープ構造体						*/
extern NUS_CUR_SHAPE_INFO		*_nu_shpinfo_ptr_;						/*	カレントシェープ構造体へのポインタ	*/

#define	NUD_OBJMOTION_INFO_MAX	1										/*	オブジェクトモーション構造体のスロット数	*/
extern NUS_CUR_OBJMOTION_INFO	_nu_obj_motion_info_[NUD_OBJMOTION_INFO_MAX];
extern NUS_CUR_OBJMOTION_INFO	*_nu_objmotinfo_ptr_;

extern NUS_SHAPE_GROUP_COEFF	*_nu_shape_buf_;
extern NUS_CSHAPELIST *_nu_shape_list_;
extern NUS_SHAPE_GROUP_COEFF	*_nu_shape_link_buf_;
extern NUS_CSHAPELIST *_nu_shape_link_list_;

extern	void (*_nu_motion_callback_)(NJS_CNK_OBJECT *obj);
extern	Sint32 _nu_motion_event_flag_;
extern	Uint16 _nu_motion_event_val_;
/*
	Prototype Declarations
*/

//	nuMotionInterpolCore.c
void	nuMotionIntLinearF3( const NUS_MKEY_F *key, Uint32 nbkeys, Float frame, Float *dst );
void	nuMotionIntLinearA3( const NUS_MKEY_A *key, Uint32 nbkeys, Float frame, Angle *dst );
void	nuMotionIntLinearA1( const NUS_MKEY_A1 *key, Uint32 nbkeys, Float frame, Angle *dst );
void	nuMotionIntLinearQ( const NUS_MKEY_QUAT *key, Uint32 nbkeys, Float frame, Float *dst );
void	nuMotionIntOverhauserF3( const NUS_MKEY_F *key, Uint32 nbkeys, Float frame, Float *dst );
void	nuMotionIntBezierF3( const NUS_MKEY_F *key, Uint32 nbkeys, Float frame, Float *dst );
void	nuMotionIntLinearSA1( const NUS_MKEY_SA1 *key, Uint32 nbkeys, Float frame, Sangle *dst );
void	nuMotionIntLinearF2( const NUS_MKEY_F2 *key, Uint32 nbkeys, Float frame, Float *dst );
void	nuMotionIntEvent( const NUS_MKEY_UI16 *key, Uint32 nbkeys, Float frame, Uint16 *dst );
void	nuMotionIntLinearSA3( const NUS_MKEY_SA *key, Uint32 nbkeys, Float frame, Sangle *dst );

#if	0	//Angle spline
void	nuMotionIntOverhauserA3( const NUS_MKEY_A *key, Uint32 nbkeys, Float frame, Angle *dst );
void	nuMotionIntBezierA3( const NUS_MKEY_A *key, Uint32 nbkeys, Float frame, Angle *dst );
void	nuMotionIntBezierA3Old( const NUS_MKEY_A *key, Uint32 nbkeys, Float frame, Angle *dst );
#endif


//	Fundamental interpolation functions
int		_nuGetMotionFloat3( Float pos[3] );
int		_nuGetMotionAngle1( Angle *pAng );
int		_nuGetMotionAngle3( Angle ang[3] );
int		_nuGetMotionQuaternion( NJS_QUATERNION *qua );
void	_nuGetShapeVlist( const NJS_CNK_MODEL *cnkmodel );
void	_nuGetShapeLinkVlist( const NJS_CNK_MODEL *cnkmodel, Sint32 **pVlist );
int		_nuGetMotionSangle1( Sangle *pAng );
int		_nuGetMotionFloat2( Float rang[2] );
int		_nuGetMotionEvent( Uint16* event );
int		_nuGetMotionSangle3( Sangle ang[3] );

//	Search Key
Uint32	_nuMotionSearchKey( const void *key, int KeySize, Uint32 nbkeys, Uint32 frame );
void	_nuGetMotionLinearKeys( const void *key, int KeySize, Uint32 nbkeys, Float frame,
								const void **pKey1, const void **pKey2, Float *pRate );
void	_nuGetMotionLinearKeys16( const void *key, int KeySize, Uint32 nbkeys, Float frame,
							 const void **pKey1, const void **pKey2, Float *pRate );

//	for multi-thread system
void	nuSetCurMotionInfoPtr( const NUS_CUR_MOTION_INFO *motion_info_ptr );
void	nuSetCurShapeInfoPtr( const NUS_CUR_SHAPE_INFO *shape_info_ptr );

//	Set Key Location(Optional)
void	_nuSetMotionKeyLocation( const NUS_MOTION *motion, int *KeyLoc, int KeyMax );



void	_nuPushPopMotion( const NJS_CNK_OBJECT *cnkobj );
void	_nuCnkPushPopShape( NJS_CNK_OBJECT *cnkobj );

void	_nuPushPopMotionLink( const NJS_CNK_OBJECT *cnkobj );
void	_nuCnkPushPopShapeLink( NJS_CNK_OBJECT *cnkobj );

#endif	/*_NU_MOTION_DEV_H_*/
