#ifndef _DNMMTH_H_
#define _DNMMTH_H_
 
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include "Mth.h"
 
/*
 * Rotation
 */	
 
typedef struct MTH_stRotation
{
    MTH_tdxReal			m_xAngle;
    MTH3D_tdstVector	m_stAxis; /* ||m_stAxis|| = 1 */
} MTH_tdstRotation;
 
/* Methods */
 
/* Accessors */
#define MTH_M_xRotationGetAngle(_p_stRotation) ((_p_stRotation)->m_xAngle)
#define MTH_M_p_stRotationGetAxis(_p_stRotation) (&(_p_stRotation)->m_stAxis)
#define MTH_M_xRotationSetAngle(_p_stRotation,_xValue) ((_p_stRotation)->m_xAngle = _xValue)
#define MTH_M_RotationSetAxis(_p_stRotation,_p_stVector) MTH3D_M_vCopyVector(&(_p_stRotation)->m_stAxis,_p_stVector)
 
/* Clone */
#define MTH_M_RotationCopyClone(_p_stDst,_p_stSrc) {\
    (_p_stDst)->m_xAngle = (_p_stSrc)->m_xAngle;\
    MTH3D_M_vCopyVector(&(_p_stDst)->m_stAxis,&(_p_stSrc)->m_stAxis);\
}
 
/* Set rotation */
#define MTH_M_RotationSet(_p_stRotation,_xAngle,_p_stAxis) {\
    MTH_M_xRotationSetAngle(_p_stRotation,_xAngle);\
    MTH_M_RotationSetAxis(_p_stRotation,_p_stAxis);\
}
 
/* Set null rotation */
#define MTH_M_RotationSetNull(_p_stRotation) {\
    (_p_stRotation)->m_xAngle = MTH_C_ZERO;\
    MTH3D_M_vNullVector(&(_p_stRotation)->m_stAxis);\
}
 
/* TRUE if null */
#define MTH_M_bRotationIsNull(_p_stRotation) (MTH_M_xRotationGetAngle(_p_stRotation) == MTH_C_ZERO)
 
 
/*
 * Move
 */	
 
typedef struct MTH_stMove
{
    MTH3D_tdstVector m_stLinear;
    MTH_tdstRotation m_stAngular;
} MTH_tdstMove;
 
/* Methods */
 
/* Accessors */
#define MTH_M_p_stMoveGetLinear(_p_stMove) (&(_p_stMove)->m_stLinear)
#define MTH_M_p_stMoveGetAngular(_p_stMove) (&(_p_stMove)->m_stAngular)
#define MTH_M_MoveSetLinear(_p_stMove,_p_stVector) MTH3D_M_vCopyVector(&(_p_stMove)->m_stLinear,_p_stVector)
#define MTH_M_MoveSetAngular(_p_stMove,_p_stRotation) MTH3D_M_vCopyVector(&(_p_stMove)->m_stAngular,_p_stRotation)
 
 
#define MTH_M_MoveSetAngularPosition(_p_stMove,_xAngle,_p_stAxis) {\
        MTH_M_xRotationSetAngle(&(_p_stMove)->m_stAngular,_xAngle);\
        MTH_M_RotationSetAxis(&(_p_stMove)->m_stAngular,_p_stAxis);\
}
 
/* Clone */
#define MTH_M_MoveCopyClone(_p_stDst,_p_stSrc) {\
    MTH3D_M_vCopyVector(&(_p_stDst)->m_stLinear,&(_p_stSrc)->m_stLinear);\
    MTH_M_RotationCopyClone(&(_p_stDst)->m_stAngular,&(_p_stSrc)->m_stAngular);\
}
 
/* Set linear part of a move to null */
#define MTH_M_MoveSetLinearToNull(_p_stMove) MTH3D_M_vNullVector(&(_p_stMove)->m_stLinear)
 
/* Set angular part of a move to null */
#define MTH_M_MoveSetAngularToNull(_p_stMove) MTH_M_RotationSetNull(&(_p_stMove)->m_stAngular)
 
/* Set null move */
#define MTH_M_MoveSetNull(_p_stMove) {\
    MTH3D_M_vNullVector(&(_p_stMove)->m_stLinear);\
    MTH_M_RotationSetNull(&(_p_stMove)->m_stAngular);\
}
 
/* Test if null */
#define MTH_M_bMoveIsNull(_p_stMove) (MTH3D_M_bIsNullVector(MTH_M_p_stMoveGetLinear(_p_stMove)) & MTH_M_bRotationIsNull(MTH_M_p_stMoveGetAngular(_p_stMove)))
 
 
 
 
/*
 *=================================================================================================
 Projection of a vector on a plane                       
 Beware : ||_p_stPlaneNorm|| = ||_p_stProjDirection)|| = 1 
 *=================================================================================================
 */
void MTH_fn_vVectorPlaneProjection
(
	MTH3D_tdstVector *_p_stResult,
	MTH3D_tdstVector *_p_stSource,
	MTH3D_tdstVector *_p_stPlaneNorm,
	MTH3D_tdstVector *_p_stProjDirection
);
 
/*
 *=================================================================================================
 Compute a rotation thanks a source vector and an image vector 
 ||_p_stSrcUnitVector|| = ||_p_stImaUnitVector|| = 1           
 *=================================================================================================
 */
 
MTH_tdstRotation *MTH_p_stRotationComputeRotationWith2Vectors
(
	MTH_tdstRotation *_p_stResult,
    MTH3D_tdstVector *_p_stSrcUnitVector,
    MTH3D_tdstVector *_p_stImaUnitVector
);
/*
 *=================================================================================================
 Rotation(Vector/Point) 
 *=================================================================================================
 */
MTH3D_tdstVector *MTH_p_stRotationMulVector
(
	MTH_tdstRotation	*_p_stRotation,
    MTH3D_tdstVector	*_p_stSource,
    MTH3D_tdstVector	*_p_stResult
);
 
 
/*
 *=================================================================================================
 Matrix -> Rotation 
 *=================================================================================================
 */
MTH_tdstRotation *MTH_p_stRotationFromMatrix 
(
	MTH_tdstRotation *_p_stResult,  
	MTH3D_tdstMatrix *_p_stRotationMatrix
);
 
 
 
 
#ifdef __cplusplus
}
#endif
 
#endif
