///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// CINEMA 4D R6 RENDERING SYSTEM //////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////© 1989-2002 MAXON Computer GmbH//////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////+++ resistance is futile +++////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

#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_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

// 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_TUBE						7
#define RT_LT_AREA						8

// 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		6
#define RT_FALLOFF_SQUARE			7
#define RT_FALLOFF_LINEAR			8
#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

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

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

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_unused;

		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
		RayPolygon	*vadr;							// polygon address
		LONG				vcnt;								// polygon count

		// textures
		TexList			*texadr;						// texture address
		LONG				texcnt;							// texture count

		// uvw
		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[6];				// object channel ID
		CHAR				flag_seenbygi;			// seen by GI flag

		BaseObject	*texture_link;			// link to real C4D object that inherited texture tag
		Vector			default_color;			// object default color

		LONG				lightrestriction_index; // index to light 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
};

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

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;					// area shadow emission width
		Real		areasamples;				// area shadow precision
};

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;					// brightness
		Real    dust;								// dust effect
		Real		dithering;					// dithering
		Bool		adaptbrightness;		// adapt brightness (angle based brightness scale)
		Bool		additive;						// additive visible light
		Vector	icol,ocol;					// inner and outer color
};

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

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

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;							// inner color
		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;				// inner color for lensflares

		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)

		LightRestriction	lr;			// light restriction
};

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
};

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
};

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
};

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,specular; // read and write
};

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;
};

#endif
