/////////////////////////////////////////////////////////////
// CINEMA 4D SDK - RENDERING SYSTEM                        //
/////////////////////////////////////////////////////////////
// +++ resistance is futile +++                            //
/////////////////////////////////////////////////////////////
// (c) 1989-2004 MAXON Computer GmbH, all rights reserved  //
/////////////////////////////////////////////////////////////

#ifndef __C4D_RAYTRACE_H
#define __C4D_RAYTRACE_H

#include "ge_math.h"
#include "ge_matrix.h"
#include "c4d_shader.h"

// texture projection types
#define P_SPHERICAL						0
#define P_CYLINDRICAL					1
#define P_FLAT								2
#define P_CUBIC								3
#define P_FRONTAL							4
#define P_SPATIAL							5
#define P_UVW									6
#define P_SHRINKWRAP					7
#define P_CAMERAMAP						8
#define P_VOLUMESHADER			 10

// object types
#define O_FLOOR								0
#define O_SKY									1
#define O_SPHERE							2
#define O_POLYGON							3

// field rendering
#define FIELD_NONE						0
#define FIELD_EVEN						1
#define FIELD_ODD							2

// depth of field
#define DOF_NONE							0
#define DOF_BOTH							1
#define DOF_FRONT							2
#define DOF_BACK							3

// anti-aliasing
#define ANTI_NONE							0
#define ANTI_GEOMETRY					1
#define ANTI_BEST							2

// camera types
#define CAMERA_PERSPECTIVE		0
#define CAMERA_PARALLEL				1
#define CAMERA_AXONOMETRIC		2
#define CAMERA_VRPANORAMA			3
#define CAMERA_CUSTOMLENS			4

// light types
#define RT_LT_OMNI						0
#define RT_LT_SPOT						1
#define RT_LT_SPOTRECT				2
#define RT_LT_DISTANT					3
#define RT_LT_PARALLEL				4
#define RT_LT_PARSPOT					5
#define RT_LT_PARSPOTRECT			6
#define RT_LT_AREA						8
#define RT_LT_AMBIENT					50 // only for OpenGL fragment programs
#define RT_LT_DEFAULT					51 // only for OpenGL fragment programs

// shadow types
#define RT_SHADOW_NONE				0
#define RT_SHADOW_SOFT				1
#define RT_SHADOW_HARD				2
#define RT_SHADOW_AREA				3

// light visibility
#define	RT_VL_NONE						0
#define RT_VL_VISIBLE					1
#define RT_VL_VOLUMETRIC			2
#define RT_VL_INVVOLUMETRIC		3

// light falloff
#define RT_FALLOFF_NONE							0
#define RT_FALLOFF_INVERSE_CLAMPED	6
#define RT_FALLOFF_SQUARE_CLAMPED		7
#define RT_FALLOFF_LINEAR						8
#define RT_FALLOFF_INVERSE					9
#define RT_FALLOFF_SQUARE					 10
#define RT_FALLOFF_STEP							5

// light noise
#define RT_VN_NONE						0
#define RT_VN_ILLUM						1
#define RT_VN_VISIB						2
#define RT_VN_BOTH						3

// light noise type
#define RT_VN_NOISE						0
#define RT_VN_SOFTTURBULENCE	1
#define RT_VN_HARDTURBULENCE	2
#define RT_VN_WAVYTURBULENCE	3

// GetRayData
#define RAY_PARAMETER					0
#define RAY_ENVIRONMENT				1
#define RAY_CAMERA						2
#define RAY_SKY								3
#define RAY_FOREGROUND				4
#define RAY_BACKGROUND				5

// render results
#define RAY_OK								0
#define RAY_NOMEM							1
#define RAY_TEXMISSING				2
#define RAY_MP								4
#define RAY_IMAGE							5
#define RAY_USERBREAK					6

// pixel fragment oversampling
#define OVERSAMPLING				 16

// raypolystate bits
#define RAYPOLYSTATE_TRIANGLE		1
#define RAYPOLYSTATE_QUADRANGLE	2
#define RAYPOLYSTATE_SPLIT			4

struct RayPolygon
{
	LONG a,b,c,d;
};

class  BaseObject;
struct TexList;
struct RayFragment;
struct PixelFragment;
class  Gradient;

#define LIGHTRESTRICTION_NODIFFUSE	(1<<0)
#define LIGHTRESTRICTION_NOSPECULAR	(1<<1)
#define LIGHTRESTRICTION_NOSHADOW		(1<<2)

#define OBJECTRESTRICTION_TRANSPARENCY	(1<<0)
#define OBJECTRESTRICTION_REFRACTION		(1<<1)
#define OBJECTRESTRICTION_REFLECTION		(1<<2)
#define OBJECTRESTRICTION_AO						(1<<4)

#define OBJECTRESTRICTION_TRANSPARENCY_INUSE (1<<3)

struct ObjectRestriction
{
	UCHAR	*object;
	LONG	object_cnt;
};

struct RayObject
{
	protected:
		RayObject(void);
	public:
		CHAR				type;										// object type
																				
		CHAR				flag_phong;							// phong flag
		CHAR				flag_castshadow;				// cast shadow flag
		CHAR				flag_receiveshadow;			// receive shadow flag
		CHAR				flag_seenbyrays;				// seen by rays flag
		CHAR				flag_seenbycamera;			// seen by camera flag
		CHAR				flag_compositing;				// compositing flag
		CHAR				flag_selfshadow;				// self shadowing flag
																				
		Vector			v2;											
																				
		Vector			mp;											// center of bounding box
		Vector			rad;										// radius of bounding box
																				
		Real				visibility;							// object visibility
		Real				phong_angle;						// phong angle
																				
		// points														
		Vector			*padr;									// point address
		LONG				pcnt;										// point count
																				
		// polygons													
		const RayPolygon	*vadr;									// polygon address
		LONG				vcnt;										// polygon count
																				
		// textures													
		TexList			*texadr;								// texture address
		LONG				texcnt;									// texture count
																				
		// uvw															
		const void	**uvwadr;								// uvw field
		LONG				uvwcnt;									// uvw entries
																				
		// polygon restriction							
		ULONG				**rsadr;								// restriction field
		LONG				rscnt;									// restriction entries
																				
		BaseObject	*link;									// link to real C4D object
																				
		Matrix			mg;											// object matrix
		Matrix			motion_delta;						// transformation matrix: oldmg * !newmg
		Real				oblurlen;								// object blur strength
																				
		CHAR				aa_minlevel;						// min/max antialiasing level
		CHAR				aa_maxlevel;						
		Real				gi_accuracy;						// global illumination accuracy
		Real				aa_threshold;						
																				
		WORD				channelid_part1[6];			// object channel ID
		CHAR				flag_seenbygi;					// seen by GI flag
		CHAR				flag_matteobject;				// object is matte object
																				
		BaseObject	*texture_link;					// link to real C4D object that inherited texture tag
		Vector			default_color;					// object default color

		LONG				restriction_index;			// index to light/object restriction table

		UCHAR				*edges;									// bits 0..3: hiding, bits 4..7: phong
		WORD				*psum;									// phong normals - access depends on mode
																				
		Matrix			mg_inverse;							// inverse object matrix

		LONG				spd_displacement;				// displacement subdivision
		Real				spd_height;							// maximum displacement height
		CHAR				spd_keepedges;					// subpixel keep edge setting
		CHAR				spd_distribution;				// subpixel distribution setting
		CHAR				spd_round;							// subpixel round setting
		CHAR				spd_roundcontour;				// subpixel round contour setting
		CHAR				spd_hqremapping;				// subpixel high quality remapping setting
		CHAR				spd_mapresult;					// subpixel map geometry setting

		void				*userdata;							// only to be used by plugin renderer				

		CHAR				flag_seenbydetails;			// detail flags, OBJECTRESTRICTION_xxx
		CHAR				flag_unused[3];

		WORD				channelid_part2[6];			// object channel ID

		ObjectRestriction	rr;								// compositing tag restriction
};

struct PolyVector
{
	Vector a,b,c,d;
};

struct RayPolyWeight
{
	Real wa,wb,wc,wd; 
};

struct RayLightNoise
{
	protected:
		RayLightNoise(void);
	public:
		LONG		type;								// noise algorithm
		Real		octaves;						// noise octaves
		Real		velocity;						// noise speed
		Real		brightness;					// noise brightness
		Real		contrast;						// noise contrast
		Bool		local;							// local noise
		Vector	scale;							// noise scale
		Real		iscale;							// illumination scale
		Vector	wind;								// wind effect
		Real		windvelocity;				// wind velocity
};

struct RayLightCaustics
{
	protected:
		RayLightCaustics(void);
	public:
		Bool		cs_enable;					// enable surface caustics
		Real		cs_energy;					// caustic energy
		LONG		cs_photons;					// number of photons

		Bool		vcs_enable;					// enable volume caustics
		Real		vcs_energy;					// volume caustic energy
		LONG		vcs_photons;				// number of volume photons

		LONG		falloff;						// caustic light falloff
		Real		innerradius;				// inner radius
		Real		outerradius;				// outer radius
};

struct RayLightShadow
{
	protected:
		RayLightShadow(void);
	public:
		Real		density;						// shadow density
		Vector	color;							// shadow color
		Bool		transparency;				// shadow supports transparency
		Bool		clippinginfluence;	// evaluate clipping areas

		LONG		mapsizex,mapsizey;	// soft shadow map resolution
		Real		bias;								// soft shadow bias
		Bool		absolute;						// absolute bias
		LONG		sampleradius;				// soft shadow sample radius
		Real		parallelwidth;			// soft shadow parallel width
		Bool		outline;						// outline soft shadow

		Bool		shadowcone;					// soft shadow cone
		Real		coneangle;					// soft shadow cone angle
		Bool		softcone;						// soft falloff at edges

		Real		areawidth_ex;				// area shadow emission width
		Real		areasamples_ex;			// no longer used
		Real		accuracy;						// area shadow accuracy
		LONG		minsamples;					// area shadow min samples
		LONG		maxsamples;					// area shadow max samples
};

struct RayLightVisible
{
	protected:
		RayLightVisible(void);
	public:
		Bool			falloff;								// falloff
		Real			strength;								// falloff strength
		Bool			edgefalloff;						// edge falloff
		Real			edgestrength;						// edge falloff strength
		Bool			colfalloff;							// colored edge falloff
		Real			innerdistance;					// inner distance
		Vector		outerdistance;					// outer distance
		Real			sampledistance;					// sample distance
		Real			brightness_multiplier;	// brightness
		Real			dust;										// dust effect
		Real			dithering;							// dithering
		Bool			adaptbrightness;				// adapt brightness (angle based brightness scale)
		Bool			additive;								// additive visible light
		Vector		icol_ex;								// no longer used
		Vector		color;

		Gradient* gradient;
};

struct RayLight
{
	protected:
		RayLight(void);
	public:
		RayLightNoise		*ln;			// pointer to noise structure
		RayLightShadow	*ls;			// pointer to shadow structure
		RayLightVisible	*lv;			// pointer to visible light structure
		BaseObject	    *link;		// link to real C4D object

		Bool		calc_illum;				// light source illuminates
		Matrix	m;								// light matrix

		LONG		type;							// type of light
		LONG		stype;						// shadow type
		LONG		vtype;						// type of visible light
		LONG		ntype;						// type of noise
		LONG		falloff;					// type of light falloff
		Real		innerangle;				// inner angle of light cone
		Real		outerangle;				// outer angle of light cone
		Real		innerradius;			// inner radius of light
		Real		outerradius;			// outer radius of light
		Real		aspectratio;			// Y distortion
		Bool		ambient;					// ambient flag
		Bool		nodiffuse;				// affects no diffuse
		Bool		nospecular;				// affects no specular
		Bool		innercolor;				// inner color different
		Bool		colfalloff;				// edge color falloff
		Bool		negative;					// negative light source
		Real		contrast;					// light contrast
		Real		innerdist;				// inner distance
		Real		outerdist;				// outer distance
		Vector	color;						// light color
		Vector	icol_ex;					// no longer used
		Bool		nearclip;					// near clipping
		Bool		farclip;					// far clipping
		Real		nearfrom;					// near clipping start
		Real		nearto;						// near clipping end
		Real		farfrom;					// far clipping start
		Real		farto;						// far clipping end
		Vector	lens_color;				// color for lensflares
		Vector  lens_icol_ex;			// no longer used

		RayLightCaustics *lc;			// pointer to caustics structure
		Bool		separatepass;			// render as separate multipass
		Real		trn;							// Exp(-contrast)
		LONG		multipass_index;	// index into multipass light field (or NOTOK)

		ObjectRestriction	lr;			// light restriction

		void*		userdata;					// only to be used by plugin renderer				

		Bool		onlyz;

		Vector	arearadius;
		LONG		areashape;
		LONG		areasamples;
		Bool    areaaddgrain;

		const Vector* area_padr;
		LONG				area_pcnt;
		const RayPolygon*	area_vadr;
		LONG				area_vcnt;
		BaseObject* area_link;
		Matrix*			area_matrix;
		Bool				shadowcaster;
		Real				area_falloffangle;
		Real				area_infiniteangle;
		Bool				area_showinrender;
		Bool				area_showinreflection;
		
		Gradient*		gradient;
		Real				gradient_multiplier;
		Real        lens_imul;			

		TexList*		texadr;
		LONG				texcnt;
};

struct RayParameter
{
	protected:
		RayParameter(void);
	public:
		LONG		xres,yres;							// image resolution
		LONG		left,top,right,bottom;	// marquee render
		Real		pixelaspect;						// aspect ratio of pixels

		LONG		unused0;
		Bool		internal_render;				// shows if an editor render is done

		LONG		antialiasing;						// antialiasing level
		LONG		oversample;							// antialiasing oversampling (1 or 16)
		Real		aa_softness;						// antialiasing softness

		LONG		reflection;							// reflection level (0: none, 1: floor and sky, 2: full)
		LONG		transparency;						// transparency level (0: none, 1: no refraction, 2: full)
		LONG		shadow;									// shadow level (0: none, 1: only soft, 2: full)

		LONG		raydepth;								// maximum ray depth
		LONG		reflectiondepth;				// maximum reflection depth
		LONG		shadowdepth;						// maximum ray depth for shadow calculations
		Real		threshold;							// minimum intensity of a ray

		LONG		unused1[2];
		LONG		field;									// field rendering
		Bool		unused2[4];
		Bool		volumetriclighting;			// volumetric effects
		Bool		straightalpha;					// straight alpha
		Bool		textures;								// textures
		Bool		textureerror;						// stop if texture error
		Bool		unused3[11];
		Bool    enable_blurry;
		Bool		dithering;							// true color dithering

		Bool		gi_enablediffuse,gi_prepass;								// radiosity options
		LONG		gi_maxdiffusedepth,gi_montecarlosamples,gi_minresolution,gi_maxresolution;
		Real		gi_accuracy,gi_strength;

		Bool		cs_enablecaustics,cs_enablevolumecaustics;	// caustics options
		LONG		cs_accuracy;
		Real		cs_stepsize,cs_sampleradius,cs_strength;

		LONG		aa_filter;							// antialiasing filter
		Real		aa_threshold;						// antialiasing threshold
		LONG		aa_minlevel;						// antialiasing minimum level
		LONG		aa_maxlevel;						// antialiasing maximum level
		Bool		aa_useobject;						// enable local antialiasing
		Real		aa_globalmip;						// global MIP scale

		LONG		gi_prepasssize;					// GI prepass size
		LONG		renderflags;						// renderflags passed to RenderDocument

		Bool		showhud;								// show head up display
		Bool		cacheshadowmaps;				// enable shadow map caching
		Bool		gi_showdiffuse;
		Bool		enablespd;
		Real		global_brightness;
		Bool		apply_ambientocclusion;
};

struct RayEnvironment
{
	protected:
		RayEnvironment(void);
	public:
		Vector  ambient;								// ambient environment color
		Bool		fogenable;							// environment fog flag
		Vector	fog;										// environment fog color
		Real    fogdistance;						// environment fog distance
		Bool    fogaffectbg;
};

struct RayCamera
{
	protected:
		RayCamera(void);
	public:
		Matrix	m;									// camera matrix
		Real		zoom;								// zoom factor (focal length divided by aperture width for parallel projections)

		LONG		type;								// camera type (e.g. CAMERA_PERSPECTIVE)
		Bool		infinite;						// if FALSE no camera plane clipping

		LONG		depthoffield;				// type of depth of field (e.g. DOF_NONE)
		Real		front_end,middle,rear_end;	// depth of field sharpness ranges

		Real		qtvr_hstart;				// horizontal start angle for QuickTime VR panorama
		Real		qtvr_hend;					// horizontal end	angle for QuickTime VR panorama
		Real		qtvr_vfov;					// vertical field of view for QuickTime VR panorama

		BaseObject	*link;					// link to real C4D camera

		Vector	off,scale;					// camera offset and scale

		Real		front_start,rear_start,front_dlt,rear_dlt;
		LONG		xdlt,ydlt;					// x/y offset for internal render

		Matrix	motion_delta;				// transformation matrix: oldmg * !newmg
		Real		clipping_plane;			// Z clipping depth if infinite is FALSE
};

struct SurfaceData
{
	Vector	col,refl,trans;
	Real		alpha;
	Ray			rray,tray;
	Vector	bumpn;
	Real		cs_generate_strength,cs_receive_strength;
};

struct RayLightComponent
{
	RayLight	*light;									// read-only
	Vector		col,lv;									// read-only
	Real			diffuse_ex,specular_ex; // read and write
	Vector		rdiffuse,rspecular;
};

struct RayLightCache
{
	RayLightComponent	**comp;							// read-only
	LONG							cnt;								// read-only
	Vector						radiosity,caustics;	// read-only
	Vector						diffuse,specular;		// read and write
};

struct PixelFragment
{
	#ifdef __API_INTERN__
	RayFragment		*next,*cluster;
	#else
	PixelFragment *next,*cluster;
	#endif

	LONG					id;

	union
	{
		UWORD	mask [OVERSAMPLING];
		ULONG lmask[OVERSAMPLING/2];
	};

	Real				z,u,v;
	Vector			col,n;

	LONG				subid; // for polygon objects: subpixel displacement ID
										 // for sphere objects: boolean value (TRUE for back side)
};

#endif
