/**\file n_3d.h
 *  3D helpers, vector and camera
 *\author Castagnier Mickael
 *\version 1.0
 *\date 30/04/2014
 */

#ifndef _N_3D_HEADER
#define _N_3D_HEADER

#ifdef __cplusplus
extern "C" {
#endif

/**\defgroup PHYSICS 3D PHYSICS: 3D movement simulations
   \addtogroup PHYSICS
  @{
*/

#include "n_log.h"
#include "n_common.h"
#include <sys/time.h>

/*! PHYSICS object state for STOPPED */
#define MOVE_STOPPED 0
/*! PHYSICS object state for move interpolated between two position */
#define MOVE_INTER 1
/*! PHYSICS object state for move simulated from latest update */
#define MOVE_SIMU 2

/*! value when the two VECTOR3D are not connected */
#define VECTOR3D_DONT_INTERSECT -2
/*! value when the two VECTOR3D are collinear */
#define VECTOR3D_COLLINEAR -1
/*! value when the two VECTOR3D are intersecting */
#define VECTOR3D_DO_INTERSECT 0

/*! struct of a point */
typedef double VECTOR3D[ 3 ];        /* x , y , z  */


/*! helper to set a VECTOR3D position */
#define VECTOR3D_SET( VECTOR , X , Y , Z ) \
   VECTOR[ 0 ] = (X) ; \
   VECTOR[ 1 ] = (Y) ; \
   VECTOR[ 2 ] = (Z) ;

/*! structure of the physics of an object */
typedef struct PHYSICS
{
    /*! last delta_t used */
    time_t delta_t ;
    /*! x,y,z actual position */
    VECTOR3D	position ;
    /*! vx,vy,vz actual speed */
    VECTOR3D speed ;
    /*! ax,ay,az actual acceleration */
    VECTOR3D acceleration ;
    /*! ax,ay,az actual rotation position */
    VECTOR3D orientation ;
    /*! rvx,rvy,rvz actual angular speed */
    VECTOR3D angular_speed ;
    /*! rax,ray,raz actual angular acceleration */
    VECTOR3D angular_acceleration ;
    /*! ability */
    int can_jump ;
    /* */
    int sz ;
} PHYSICS ;

/* distance between two points */
double distance( VECTOR3D p1, VECTOR3D p2 );
/* update componant[ it ] of a VECTOR3D */
int update_physics_position_nb( PHYSICS *object, int it, double delta_t );
/* update componant[ it ] of a VECTOR3D, reversed time */
int update_physics_position_reverse_nb( PHYSICS *object, int it, double delta_t );
/* update the position of an object, using the delta time T to update positions */
int update_physics_position( PHYSICS *object, double delta_t );
/* update the position of an object, using the delta time T to reverse update positions */
int update_physics_position_reverse( PHYSICS *object, double delta_t );
/* compute if two vector are colliding, storing the resulting point in px */
int vector_intersect( VECTOR3D p0, VECTOR3D p1, VECTOR3D p2, VECTOR3D p3, VECTOR3D *px );

/*! VECTOR3D copy wrapper */
#define copy_point( __src_ , __dst_ ) \
   memcpy( __dst_ , __src_ , sizeof( VECTOR3D ) );

/**
@}
*/

#ifdef __cplusplus
}
#endif


#endif
