/*======================================================================*/
/* 3DLib								*/
/*									*/
/* Camera header file							*/
/*									*/
/* AUTHOR:	Gabor Nagy						*/
/* DATE:	1996-Dec-12 23:29:28					*/
/*									*/
/* 3DLib(TM) Copyright (C) 1995 by Gabor Nagy. All rights reserved.	*/
/*======================================================================*/
#ifndef _E3DCamera_h
#define _E3DCamera_h

#ifndef _E3DModel_h
#include <E3D/Model.h>
#endif

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

// Display formats
//
enum
{
 E3dNTSC=0,
 E3dPAL,
 E3dVESA640x480,
};

// Lens types
//
enum
{
 E3dLENS_ORTHO=0,
 E3dLENS_PERSPECTIVE,
 E3dLENS_FISHEYE,
 E3dLENS_REAR_FISHEYE,	// Fish-eye looking backward. Along with the forward-looingg fisheye, used to make a full 360 degree views / environment maps
 E3dLENS_PANORAMA,	// 360-degree panorama view
 E3dLENS_SPHERICAL,	// Full 360-degree view spherical map
 E3dLENS_ANGLE_MAP	// 360x360 degree angle map
};


typedef struct
{
 int			RefCnt;				// Reference count
 char*			Name;

 E3d3DPosition		Position;
 E3d3DPosition		InterestPoint;
 E3dVector		UpVector;
 E3dAngle		FieldOfView;			// Field of view in degrees
 E3dCoordinate		ZNear, ZFar;
 E3dCoordinate		EyeDistance;			// 3D eye-distance for stereoscopic camera
 double			XZoom, YZoom;			// For orthogonal views

 float			ShutterTime;
// Lens
//
 E3dCoordinate		FocalLength, Aperture;
 unsigned int		LensType;


// Film (image sensor)
//
 double			AspectRatio;
 float			GlowThreshold, GlowRadius;
 EBool			Glow;


// Stuff calculated internally
//
 E3dMatrix		WorldToViewerMatrix,		// Camera transformation matrix
			WorldToLeftViewerMatrix,	// For stereoscopic Camera
			WorldToRightViewerMatrix,	// For stereoscopic Camera
			CameraMatrix,			// Inverse Camera transformation matrices (for control-models etc.)
			LeftCameraMatrix,
			RightCameraMatrix,
			InterestMatrix;			// Matrix to display the interest point

 E3dMatrix		ProjectionMatrix;

 E3dCoordinate		ViewDistance;			// Distance of the camera and the interest point
 E3dVector		Direction;			// The unit length vector of the line-of-sight (for distance setting)
 float			Latitude, Longitude;		// Orbital angles (y,x)
 float			BankAngle;

 E3dModel*		Model;				// The 3D icon representing this Camera (it's Child is the interest point)

 E3dModel*		PositionConstraint;		// Model to constrain posistion to
 E3dModel*		AlignmentConstraint;		// Model to which to align the camera
 E3dModel*		InterestConstraint;		// Model to which to have the camera to look at

 unsigned int		NumOfCallbacks;
 E3dCallbackRec*	Callbacks;
} E3dCamera;



typedef struct
{
// E3dNodeInfo part
//
 E3dModelClass*	Class;

// E3dCameraInfo part
//
 E3dCamera*	Camera;
} E3dCameraInfo;



/*--------------------------------------------------------------*/
/* Global variables						*/
/*--------------------------------------------------------------*/
extern E3dCameraInfo	E3d_CameraModelInfo;


/*--------------------------------------------------------------*/
/* Function prototypes						*/
/*--------------------------------------------------------------*/
extern void	E3d_CameraCalcOrbit(E3dCamera* LCamera);
extern void	E3d_OrbitCamera(E3dCamera* LCamera, double LLongitude, double LLatitude);

extern void	E3d_CameraCalcUpVector(E3dCamera* LCamera);
extern void	E3d_CameraDefault(E3dCamera* LCamera);
extern void	E3d_CameraSet(E3dCamera* LCamera, double LXPos, double LYPos, double LZPos, double LFieldOfView, double LZoom, double LZNear, double LZFar, double LEyeDistance);

extern void	E3d_CameraRefreshMatrices(E3dCamera* LCamera);

extern void	E3d_CameraUpdateViewDirection(E3dCamera* LCamera);
extern void	E3d_CameraSetViewDistance(E3dCamera* LCamera, double LDistance);
extern void	E3d_CameraSetPosition(E3dCamera* LCamera, E3d3DPosition* LPosition);
extern void	E3d_CameraSetInterest(E3dCamera* LCamera, E3d3DPosition* LPosition);

extern E3dCamera*	E3d_CameraAllocate();
extern void		E3d_CameraFree(E3dCamera* LCamera);

extern void		E3d_CameraCopy(E3dCamera* LSCamera, E3dCamera* LDCamera);


extern void	E3d_CameraAddCallback(E3dCamera* LCamera, E3dCallbackProc LCallbackProc, EPointer LClientData);
extern void	E3d_CameraRemoveCallback(E3dCamera* LCamera, E3dCallbackProc LCallbackProc, EPointer LClientData);

extern E3dModelInfo*	E3d_CameraCreateModelInfo(E3dCamera* LCamera);

extern void	E3d_CameraGetViewPlaneOnPoint(E3dCamera* LCamera, E3dCoordinate LX, E3dCoordinate LY, E3dCoordinate LZ, E3dPlane* LPlane);



#ifdef USEOpenGL
extern void	E3dGL_CameraLookAt(E3dCamera* LCamera);
extern void	E3dGL_CameraPerspective(E3dCamera* LCamera);
extern void	E3dGL_CameraPickMatrix(GLdouble LX, GLdouble LY, GLdouble LXSize, GLdouble LYSize, const GLint LViewPort[4]);
#endif // USEOpenGL



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

#endif	// _E3DCamera_h
