/* vectortype.h: vector type definitions */

#ifndef _VECTORTYPE_H_
#define _VECTORTYPE_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <math.h>

/* a vector in 3D space */
typedef struct VECTOR {
	float x, y, z;
} VECTOR;

/* a vector in 2D space */
typedef struct VEC2D {
	float 	u, v;
} VEC2D;

/* a vector in 4D space */
typedef struct VEC4D {
	float x, y, z, w;
} VEC4D;

/* double floating point vectors: The extra precision is sometimes needed eg
 * for sampling a spherical triangle or computing an analytical point to
 * patch factor, also for accurately computing normals and areas ... */
typedef struct DVECTOR {
	double x, y, z;
} DVECTOR;

typedef struct DVEC2D {
	double 	u, v;
} DVEC2D;

typedef struct DVEC4D {
	double x, y, z, w;
} DVEC4D;


/* Packed vectors for saving memory.
   Currently only for unit vectors */

typedef struct PACKEDUNITVECTOR {
  char x,y,z;

#ifdef __cplusplus
  // assignment operator
  inline PACKEDUNITVECTOR operator= (VECTOR v)
  {
    x = (char)(int)(v.x * 127);
    y = (char)(int)(v.y * 127);
    z = (char)(int)(v.z * 127);

    return *this;
  }

#endif

} PACKEDUNITVECTOR;



#define POINT VECTOR
#define POINT2D VEC2D
#define POINT4D VEC4D
#define DPOINT DVECTOR
#define DPOINT2D DVEC2D
#define DPOINT4D DVEC4D

/* memory management routines, to store vectors in linear lists or other generic
 * data structures of the GDT library */

/* creates a vector with given components */
extern VECTOR *VectorCreate(float x, float y, float z);

/* destroys a vector */
extern void VectorDestroy(VECTOR *vector);

/* duplicates a vector */
extern VECTOR *VectorCopy(VECTOR *vector);

/* compute the distance between two 3D points */
extern double VectorDist(DVECTOR *p1, DVECTOR *p2);

/* The routines below were copied from the rayshade source files. */

/* normalizes the vector and returns the norm. Other difference with 
 * VECTORNORMALIZE is that it is explicitely tested that the components of the 
 * vector are within [-1,1] */
extern double VectorNormalize(VECTOR *vector);

/*
 * Find the "dominant" part of the vector (eg patch-normal).  This
 * is used to turn the point-in-polygon test into a 2D problem.
 */
extern int VectorDominantCoord(VECTOR *v);

#ifdef __cplusplus
}
#endif

#endif /*_VECTORTYPE_H_*/
