/*======================================================================*/
/* 3DLib								*/
/* Basic type definitions header file					*/
/*									*/
/* AUTHOR:	Gabor Nagy						*/
/* DATE:	1996-Dec-12 23:48:25					*/
/*									*/
/* 3DLib(TM) Copyright (C) 1995 by Gabor Nagy. All rights reserved.	*/
/*======================================================================*/
#ifndef	_E3DTypes_h
#define	_E3DTypes_h

#include <float.h>

#include <ETypes.h>
#include <Color/Color.h>


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif

// A general NOTHING, NONE etc. value
//
#define E3dNONE				0


/*--------------------------------------------------------------*/
/* If the symbol E3dDOUBLE_PRECISION is defined, the 3D library	*/
/* will use double precision for all computations		*/
/*--------------------------------------------------------------*/
//#define E3dDOUBLE_PRECISION

/*--------------------------------------------------------------*/
/* If these files are included, the 3D library will use OpenGL	*/
/*--------------------------------------------------------------*/
#ifdef USEOpenGL
#include <GL/gl.h>

#ifdef E3dDOUBLE_PRECISION
#define MglLoadMatrix	glLoadMatrixd
#define MglMultMatrix	glMultMatrixd
#define MglGetFloatV	glGetDoublev
#define MglTranslate	glTranslated
#define MglRotate	glRotated
#define MglScale	glScaled
#else
#define MglLoadMatrix	glLoadMatrixf
#define MglMultMatrix	glMultMatrixf
#define MglGetFloatV	glGetFloatv
#define MglTranslate	glTranslatef
#define MglRotate	glRotatef
#define MglScale	glScalef
#endif // DOUBLE_PRECISION

#endif // USEOpenGL

/*--------------------------------------------------------------*/
/* If this symbol is defined, the 3D library uses GUI		*/
/* (Creates/manages pseudo models for lights, cameras etc.)	*/
/*--------------------------------------------------------------*/
#define _E3dGUI


#define E3dPI		3.14159265358979323846264
#define E3dINV_PI	(1.0/E3dPI)

#define	E3dMAX_HIERARCHY_DEPTH		256


/*------------------------------------------------------*/
/* Macros						*/
/*------------------------------------------------------*/
#define E3dM_ABS(x)	(((x<0)?(-x):(x)))
#define E3dM_MIN(a,b)	((a<=b)?a:b)
#define E3dM_MAX(a,b)	((a>=b)?a:b)

#define E3dM_MINMAX(mA, mB, mMin, mMax)\
 if(mA<mB) { mMin=mA;mMax=mB; }\
 else { mMin=mB;mMax=mA; }



/*------------------------------------------------------*/
/* Type definitions					*/
/*------------------------------------------------------*/
#define	E3dRADIANS_TO_DEGREES	57.295779513082320877
#define E3dDEGREES_TO_RADIANS	0.017453292519943295769

#define	E3dNOMODEL	-1

enum { E3dGLSHORT=0,E3dGLLONG,E3dGLSINGLE,E3dGLDOUBLE };


#ifndef M00

#define M00	0
enum
{
    M01=1, M02, M03,
 M10, M11, M12, M13,
 M20, M21, M22, M23,
 M30, M31, M32, M33
};

#endif	// M00



#define E3dMtxPos(r, c)	(c*4+r)


#ifdef E3dDOUBLE_PRECISION
#define E3dEPSILON	0.0000001
typedef double	E3dType;
typedef double	E3dGLType;
typedef double	E3dGLCoordinate;
typedef double	E3dCoordinate;
typedef double	E3dAngle;
typedef double	E3dWeight;
typedef double	E3dFColorComponent;
typedef double	E3dMatrix[16];
#else
#define E3dEPSILON	0.00001
typedef float	E3dType;
typedef float	E3dGLType;
typedef float	E3dGLCoordinate;
typedef float	E3dCoordinate;
typedef float	E3dAngle;
typedef float	E3dWeight;
typedef float	E3dFColorComponent;
typedef float	E3dMatrix[16];
#endif // DOUBLE_PRECISION



// What to include in bounding box calculations
//
#define E3dBB_NONE		0
#define E3dBB_SELECTED_GEOMETRY	1
#define E3dBB_TAGGED_POINT	(1<<1)
#define E3dBB_ALL		3



enum
{
 E3dX=0, E3dY, E3dZ, E3dW
};

// Rotation orders
//
enum
{
 E3dXYZ=1,
 E3dXZY,
 E3dYXZ,
 E3dYZX,
 E3dZXY,
 E3dZYX
};



typedef struct
{
 E3dCoordinate	X, Y, Z;
 E3dAngle	Angle;			// cosine of the angle
} E3dQuaternion;


typedef struct
{
 E3dCoordinate	Translate[3];
 E3dCoordinate	Scale[3];
 E3dAngle	RotationAngles[3];	// Euler angles
 E3dQuaternion	Orientation;		// Quaternion
 E3dMatrix	RotMatrix;		// Rotation matrix
} E3dDecompMatrix;


#define E3dMACHINE_ERROR	0.00001
#define E3dTRI_ERR		-1
#define E3dCOLINERR	3*E3dMACHINE_ERROR	// One for each subtraction



#define E3dGLPIXELFORMAT	GL_ABGR_EXT
#define E3dGLPIXELTYPE		GL_UNSIGNED_BYTE

#define E3dALLOCQUICK	1
#define E3dALLOCFORGL	2

#define	E3dNO	0
#define	E3dYES	1

#define E3dDEF_AMBIENCE	0.32

#define E3dDO_NONE	0
#define E3dDO_X		1
#define E3dDO_Y		(1<<1)
#define E3dDO_Z		(1<<2)
#define E3dDO_ALL	0x7


#define E3dALL		0xFFFFFFFF


#define E3dPOLY_DIRECTION	1	// 1: Exterior contours are defined anti clockwise

typedef void*	E3dPointer;

typedef struct
{
 E3dCoordinate	X, Y;
} E3d2DPosition;


// 2D texture coordinates
//
typedef struct
{
 float		S, T;
} E3dST;


// Integer 3D position
//
typedef struct
{
 int	X, Y, Z;
} E3d3DPositionI;


typedef struct
{
 E3dCoordinate	X, Y, Z;
} E3d3DPosition;


// Homogeneous position
//
typedef struct
{
 E3dCoordinate	X, Y, Z, W;
} E3dHPosition;





// Point used for shading surfaces
//
typedef struct
{
 E3dCoordinate	X, Y, Z;				// Position
 E3dCoordinate	NormalX, NormalY, NormalZ;		// Normal
 E3dCoordinate	TangentX, TangentY, TangentZ;
} E3dSurfacePoint;


typedef struct
{
 E3dAngle	X, Y, Z;
} E3dRotation;


typedef struct
{
 E3dCoordinate	X, Y, Z, Length;
} E3dVector;


typedef struct
{
 E3dCoordinate	A, B, C, D;	// Plane coefficients for the implicit formula (Ax+By+Cz+D=0)
} E3dPlane;


#define MAX_HIERARCHYDEPTH	 32


#define MAX_MODELWINDOWNUM	4

#define	E3dDFUNCT_NONE		0			// Scene display disabled on window
#define	E3dDFUNCT_STANDARD	1			// Scene displayed by the standard function
#define	E3dDFUNCT_CUSTOM	(1<<1)			// Scene displayed by custom function


enum
{
 E3dMDL_BINARY=0,
 E3dMDL_ASCII
};



// Callback reasons
//
enum
{
 E3dCR_PICK=1,
 E3dCR_ABORT		// E.g. Esc was pressed
};


// Callbacks
//
typedef void	(*E3dCallbackProc)(void*, EPointer, EPointer);

typedef struct E3dCallbackRec
{
 E3dCallbackProc	Proc;
 EPointer		ClientData;
} E3dCallbackRec;


// Interface call reasons
//
enum
{
 E3dICR_POINT_CHANGED=1,
 E3dICR_POINTS_CHANGED
};



typedef EBool	(*E3dInterfaceProc)(void*, EPointer, EPointer);		// Return value: TRUE if redraw is needed

// For linking Items via Inputs and Outputs
//
typedef struct E3dInterface
{
 E3dInterfaceProc	Proc;
 EPointer		ClientData;
} E3dInterface;



// EditProc return values
//
enum
{
 E3dEDITP_INFO_ADDED=0,
 E3dEDITP_IN_USE,
 E3dEDITP_EDITING,
 E3dEDITP_NOTHING
};




//----------------------------------------
// KD trees
//----------------------------------------
typedef struct E3dKDNode_S	E3dKDNode;

#define E3dKDNodeCore()\
 int		RefCnt;				/* Reference count	*/\
 E3dKDNode*	Parent;				/* Hierarchy links	*/\
 E3dKDNode*	PrevSibling;\
 E3dKDNode*	NextSibling;\
 E3dKDNode*	Child;\
 E3dKDNode*	Prev;\
 E3dKDNode*	Next


struct E3dKDNode_S		// For forward declarations
{
 E3dKDNodeCore();
};


extern E3dKDNode*	E3d_KDNodeAllocate(unsigned int LStructSize);
extern void		E3d_KDTreeFree(E3dKDNode* LNode);
extern void		E3d_KDTreeAddSet(E3dKDNode* LTree, int LDepth);




/********************************/
/* Macros			*/
/********************************/
#define E3dM_PARGBToPABGR(PRGB) (((PRGB&0xFF000000)|((PRGB&0x000000FF)<<16)|(PRGB&0x0000FF00)|((PRGB&0x00FF0000)>>16)))

/*----------------------------------------------*/
/* GL-specific data				*/
/*----------------------------------------------*/
#ifndef _GHType
#define _GHType
enum		// Graphics hardware types
{
 GH_B_or_G=0,
 GH_GT,
 GH_GTX,
 GH_VGX,
 GH_VGXT,
 GH_RealityEngine,
 GH_Personal_Iris,
 GH_Personal_Iris_with_Turbo_Graphics,
 GH_Personal_Iris_early_serial_numbers,
 GH_Entry,
 GH_XS,
 GH_XS24,
 GH_XZ,
 GH_Elan,
 GH_Extreme,
 GH_Indy,
 GH_Unknown
};
#endif

#define	E3dGETRED		 1
#define	E3dGETGREEN		(1<<1)
#define	E3dGETBLUE		(1<<2)
#define	E3dGETALPHA		(1<<3)
#define	E3dGETINTENSITY		(1<<4)


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration which encloses file.
#endif


#endif	// _E3DTypes_h
