// Copyright (C) 2004 Id Software, Inc.
//

#ifndef __RENDERWORLD_H__
#define __RENDERWORLD_H__

/*
===============================================================================

	Render World

===============================================================================
*/

class idDemoFile;

// RAVEN BEGIN
// jscott: new proc format
//#define	PROC_FILE_ID					"mapProcFile003"
#define PROC_FILE_ID					"PROC"
#define PROC_FILE_EXT					"proc"
#define PROC_FILEVERSION				"4" // jmarshall: changed to string. 
// RAVEN END

// RAVEN BEGIN
// dluetscher: new MD5RProc file format
#define MD5R_PROC_FILE_ID				"MD5RProcVersion"
#define MD5R_PROC_FILE_EXT				"MD5RProc"
#define MD5R_PROC_FILEVERSION			4
// RAVEN END

// shader parms
const int MAX_GLOBAL_SHADER_PARMS	= 12;

const int SHADERPARM_RED			= 0;
const int SHADERPARM_GREEN			= 1;
const int SHADERPARM_BLUE			= 2;
const int SHADERPARM_ALPHA			= 3;
const int SHADERPARM_TIMESCALE		= 3;
const int SHADERPARM_TIMEOFFSET		= 4;
const int SHADERPARM_DIVERSITY		= 5;	// random between 0.0 and 1.0 for some effects (muzzle flashes, etc)
const int SHADERPARM_MODE			= 7;	// for selecting which shader passes to enable
const int SHADERPARM_TIME_OF_DEATH	= 7;	// for the monster skin-burn-away effect enable and time offset

// model parms
const int SHADERPARM_MD5_SKINSCALE	= 8;	// for scaling vertex offsets on md5 models (jack skellington effect)

const int SHADERPARM_MD3_FRAME		= 8;
const int SHADERPARM_MD3_LASTFRAME	= 9;
const int SHADERPARM_MD3_BACKLERP	= 10;

const int SHADERPARM_BEAM_END_X		= 8;	// for _beam models
const int SHADERPARM_BEAM_END_Y		= 9;
const int SHADERPARM_BEAM_END_Z		= 10;
const int SHADERPARM_BEAM_WIDTH		= 11;

const int SHADERPARM_SPRITE_WIDTH		= 8;
const int SHADERPARM_SPRITE_HEIGHT		= 9;

const int SHADERPARM_PARTICLE_STOPTIME = 8;	// don't spawn any more particles after this time

// guis
const int MAX_RENDERENTITY_GUI		= 3;

// RAVEN BEGIN
// jscott: for effect brightness
const int SHADERPARM_BRIGHTNESS		= 6;	// for the overall brightness of effects
// RAVEN END

// RAVEN BEGIN
// dluetscher: added a default value for light detail levels
#define DEFAULT_LIGHT_DETAIL_LEVEL	10.f
// RAVEN END 

enum {
	RD_MISC = 0,
	RD_RENDERVIEW,
	RD_RENDER_STATE,

	RD_RENDERENT_UPDATE,
	RD_RENDERENT_FREE,
	RD_RENDERENT_ADD,
	RD_RENDERENT,

	RD_RENDERLIGHT_UPDATE,
	RD_RENDERLIGHT_FREE,
	RD_RENDERLIGHT_ADD,
	RD_RENDERLIGHT,

	RD_RENDEREFFECT_UPDATE,
	RD_RENDEREFFECT_FREE,
	RD_RENDEREFFECT_STOP,
	RD_RENDEREFFECT_ADD,
	RD_RENDEREFFECT,

	RD_SOUND_STATE,
	RD_SOUND,

	RD_HUD,

	RD_MAX_STATS
};
struct renderEntity_s;
struct renderView_s;
typedef bool(*deferredEntityCallback_t)( renderEntity_s *, const renderView_s * );

enum {
	REF_OUTLINE_NODEPTH = 1 << 0
};

// RAVEN BEGIN
// bdube: attachments
typedef struct attachedModel_s {
	idRenderModel*	model;
	jointHandle_t	joint;
} attachedModel_t;
// RAVEN END

typedef struct renderEntity_s {
	idRenderModel *			hModel;				// this can only be null if callback is set

	int						entityNum;
	int						bodyId;

	// Entities that are expensive to generate, like skeletal models, can be
	// deferred until their bounds are found to be in view, in the frustum
	// of a shadowing light that is in view, or contacted by a trace / overlay test.
	// This is also used to do visual cueing on items in the view
	// The renderView may be NULL if the callback is being issued for a non-view related
	// source.
	// The callback function should clear renderEntity->callback if it doesn't
	// want to be called again next time the entity is referenced (ie, if the
	// callback has now made the entity valid until the next updateEntity)
	idBounds				bounds;					// only needs to be set for deferred models and md5s
	deferredEntityCallback_t	callback;

	void *					callbackData;			// used for whatever the callback wants

	// player bodies and possibly player shadows should be suppressed in views from
	// that player's eyes, but will show up in mirrors and other subviews
	// security cameras could suppress their model in their subviews if we add a way
	// of specifying a view number for a remoteRenderMap view
	int						suppressSurfaceInViewID;
	int						suppressShadowInViewID;

	// world models for the player and weapons will not cast shadows from view weapon
	// muzzle flashes
	int						suppressShadowInLightID;

	// if non-zero, the surface and shadow (if it casts one)
	// will only show up in the specific view, ie: player weapons
	int						allowSurfaceInViewID;

// RAVEN BEGIN
// bdube: hiding surfaces
	// Mask of surfaces which should be suppresesed when rendering the entity
	int						suppressSurfaceMask;
// RAVEN END	

	// positioning
	// axis rotation vectors must be unit length for many
	// R_LocalToGlobal functions to work, so don't scale models!
	// axis vectors are [0] = forward, [1] = left, [2] = up
	idVec3					origin;
	idMat3					axis;

	// texturing
	const idMaterial *		customShader;			// if non-0, all surfaces will use this
	const idMaterial *		referenceShader;		// used so flares can reference the proper light shader
// RAVEN BEGIN
// bdube: overlay shaders
	const idMaterial *		overlayShader;			// overlays the model on top of itself with this shader (originally for powerups)
// RAVEN END	
	const idDeclSkin *		customSkin;				// 0 for no remappings
// RAVEN BEGIN
	int						referenceSoundHandle;	// for shader sound tables, allowing effects to vary with sounds
// RAVEN END	
	float					shaderParms[ MAX_ENTITY_SHADER_PARMS ];	// can be used in any way by shader or model generation

	// Optional presentation-only visibility effects. An alpha value <= 0 disables
	// the effect for this entity.
	idVec4					outlineColor;
	idVec4					rimlightColor;
	idVec4					brightSkinColor;
	float					outlineWidth;
	int						outlineFlags;
  
// RAVEN BEGIN
// mwhitlock: Xenon texture streaming
#if defined(_XENON)
	idList<idMaterial *>	allMaterials;
#endif
// RAVEN END

  	// networking: see WriteGUIToSnapshot / ReadGUIFromSnapshot
	class idUserInterface * gui[ MAX_RENDERENTITY_GUI ];

	struct renderView_s	*	remoteRenderView;		// any remote camera surfaces will use this

	int						numJoints;
	idJointMat *			joints;					// array of joints that will modify vertices.
													// NULL if non-deformable model.  NOT freed by renderer

	float					modelDepthHack;			// squash depth range so particle effects don't clip into walls

	// options to override surface shader flags (replace with material parameters?)
	bool					noSelfShadow;			// cast shadows onto other objects,but not self
	bool					noShadow;				// no shadow at all

	bool					noDynamicInteractions;	// don't create any light / shadow interactions after
													// the level load is completed.  This is a performance hack
													// for the gigantic outdoor meshes in the monorail map, so
													// all the lights in the moving monorail don't touch the meshes

// RAVEN BEGIN
	bool					forceUpdate;			// force an update

// bdube: weapon depth hack only in a given view id
	int						weaponDepthHackInViewID;// squash depth range so view weapons don't poke into walls
// RAVEN END	
													// this automatically implies noShadow
												
// RAVEN BEGIN
// ddynerman: Wolf LOD code
	float					shadowLODDistance;
	int						suppressLOD;
// RAVEN END

// jmarshall
	int						referenceSound;
// jmarshall end
} renderEntity_t;

typedef struct renderLight_s {
	idMat3					axis;				// rotation vectors, must be unit length
	idVec3					origin;

	// if non-zero, the light will not show up in the specific view,
	// which may be used if we want to have slightly different muzzle
	// flash lights for the player and other views
	int						suppressLightInViewID;

	// if non-zero, the light will only show up in the specific view
	// which can allow player gun gui lights and such to not effect everyone
	int						allowLightInViewID;

// RAVEN BEGIN
// dluetscher: added a min light detail level setting that describes when this light is visible
	float					detailLevel;
// RAVEN END

	// I am sticking the four bools together so there are no unused gaps in
	// the padded structure, which could confuse the memcmp that checks for redundant
	// updates
	bool					noShadows;			// (should we replace this with material parameters on the shader?)
	bool					noSpecular;			// (should we replace this with material parameters on the shader?)
// RAVEN BEGIN
// ddynerman: no dynamic shadows - allows dmap to create optimized static shadows, but prevents dynamic shadows
	bool					noDynamicShadows;	
// RAVEN END

	bool					pointLight;			// otherwise a projection light (should probably invert the sense of this, because points are way more common)
	bool					parallel;			// lightCenter gives the direction to the light at infinity
	bool					globalLight;		// Whether this is a global light or not.
	idVec3					lightRadius;		// xyz radius for point lights
	idVec3					lightCenter;		// offset the lighting direction for shading and
												// shadows, relative to origin

	// frustum definition for projected lights, all reletive to origin
	// FIXME: we should probably have real plane equations here, and offer
	// a helper function for conversion from this format
	idVec3					target;
	idVec3					right;
	idVec3					up;
	idVec3					start;
	idVec3					end;

	// Dmap will generate an optimized shadow volume named _prelight_<lightName>
	// for the light against all the _area* models in the map.  The renderer will
	// ignore this value if the light has been moved after initial creation
	idRenderModel *			prelightModel;

	// muzzle flash lights will not cast shadows from player and weapon world models
	int						lightId;


	const idMaterial *		shader;				// NULL = either lights/defaultPointLight or lights/defaultProjectedLight
	float					shaderParms[MAX_ENTITY_SHADER_PARMS];		// can be used in any way by shader
// RAVEN BEGIN
	int						referenceSoundHandle;		// for shader sound tables, allowing effects to vary with sounds
// mwhitlock: Xenon texture streaming
#if defined(_XENON)
	idList<idMaterial *>	allMaterials;
#endif
// RAVEN END

// jmarshall
	int						referenceSound;
// jmarshall end
} renderLight_t;

// RAVEN BEGIN
// jscott: for handling of effects
typedef struct renderEffect_s {

	const idDecl			*declEffect;

	float					startTime;
	int						suppressSurfaceInViewID;
	int						allowSurfaceInViewID;
	int						groupID;

	idVec3					origin;
	idMat3					axis;

	idVec3					gravity;
	idVec3					endOrigin;

	float					attenuation;
	bool					hasEndOrigin;
	bool					loop;						// effect is looping
	bool					ambient;					// effect is from an entity
	bool					inConnectedArea;
	int						weaponDepthHackInViewID;	// squash depth range so view weapons don't poke into walls
	float					modelDepthHack;	

	int						referenceSoundHandle;		// for shader sound tables, allowing effects to vary with sounds

	float					shaderParms[ MAX_ENTITY_SHADER_PARMS ];	// can be used in any way by shader or model generation
} renderEffect_t;
// RAVEN END

typedef struct renderView_s {
	// player views will set this to a non-zero integer for model suppress / allow
	// subviews (mirrors, cameras, etc) will always clear it to zero
	int						viewID;

	// sized from 0 to SCREEN_WIDTH / SCREEN_HEIGHT (640/480), not actual resolution
	int						x, y, width, height;

	float					fov_x, fov_y;
	idVec3					vieworg;
	idMat3					viewaxis;			// transformation matrix, view looks down the positive X axis

	bool					cramZNear;			// for cinematics, we want to set ZNear much lower
	bool					forceUpdate;		// for an update 

	// time in milliseconds for shader effects and other time dependent rendering issues
	int						time;
	float					shaderParms[MAX_GLOBAL_SHADER_PARMS];		// can be used in any way by shader
	const idMaterial		*globalMaterial;							// used to override everything draw

// RAVEN BEGIN
// mwhitlock: Xenon texture streaming.
#if defined(_XENON)
	bool					streamingPrecache;	// If true, we precache all the textures that are visible in the world
#endif
// RAVEN END
} renderView_t;


// exitPortal_t is returned by idRenderWorld::GetPortal()
typedef struct {
	int					areas[2];		// areas connected by this portal
	const idWinding	*	w;				// winding points have counter clockwise ordering seen from areas[0]
	int					blockingBits;	// PS_BLOCK_VIEW, PS_BLOCK_AIR, etc
	qhandle_t			portalHandle;
} exitPortal_t;


// guiPoint_t is returned by idRenderWorld::GuiTrace()
typedef struct {
	float				x, y;			// 0.0 to 1.0 range if trace hit a gui, otherwise -1
	int					guiId;			// id of gui ( 0, 1, or 2 ) that the trace happened against
	float				fraction;		// fraction of trace completed before hitting the gui surface
} guiPoint_t;


// modelTrace_t is for tracing vs. visual geometry
typedef struct modelTrace_s {
	float					fraction;			// fraction of trace completed
	idVec3					point;				// end point of trace in global space
	idVec3					normal;				// hit triangle normal vector in global space
	const idMaterial *		material;			// material of hit surface
	const renderEntity_t *	entity;				// render entity that was hit
	int						jointNumber;		// md5 joint nearest to the hit triangle

// RAVEN BEGIN
// jscott: added block
	const rvDeclMatType *	materialType;
// RAVEN END
} modelTrace_t;

// RAVEN BEGIN
// abahr: changed to 4 to include gravity
static const int NUM_PORTAL_ATTRIBUTES = 4;
// RAVEN END

typedef enum {
	PS_BLOCK_NONE = 0,

	PS_BLOCK_VIEW = 1,
	PS_BLOCK_LOCATION = 2,		// game map location strings often stop in hallways
	PS_BLOCK_AIR = 4,			// windows between pressurized and unpresurized areas
// RAVEN BEGIN
// abahr
	PS_BLOCK_GRAVITY = 8,		// PS_BLOCK_ALL does not block gravity.  Must use info_gravityseperator

	PS_BLOCK_ALL = PS_BLOCK_VIEW|PS_BLOCK_LOCATION|PS_BLOCK_AIR
// RAVEN END
} portalConnection_t;


// RAVEN BEGIN
// AReis: Render flags.
enum
{
	RF_NORMAL					= 0,
	// Let the renderer know its in a editor of sorts.
	RF_IS_EDITOR				= BIT( 0 ),
	// Viewdef is fullscreen and is 2d (mostly for main menu)
	RF_IS_FULLSCREEN_2D			= BIT( 1 ),
	// Don't draw the GUI, just the world.
	RF_NO_GUI					= BIT( 2 ),
	// Only draw the GUI, not the world.
	RF_GUI_ONLY					= BIT( 3 ),
// RAVEN BEGIN
// dluetscher: added render flag to denote that penumbra map rendering is desired 
	RF_PENUMBRA_MAP				= BIT( 4 ),
// dluetscher: added render flag that defers the command buffer submission of render 
//			   commands until the first non-deferred render command (with the exception of 
//			   certain render commands like RC_DRAW_PENUMBRA_MAPS - which ignores deferred
//			   render commands and lets them get submitted past)
	RF_DEFER_COMMAND_SUBMIT		= BIT( 5 ),
	// this is a portal sky view
	RF_PORTAL_SKY				= BIT( 6 ),
	// this the primary view - when this is rendered, we then know we can capture the screen buffer
	RF_PRIMARY_VIEW				= BIT( 7 ),
// RAVEN END
};

// RAVEN END


// RAVEN BEGIN
// jscott: effect handling in the renderer
class rvRenderEffect {
public:
	virtual					~rvRenderEffect(void) {}
};
// RAVEN END

class rvRenderEffectLocal : rvRenderEffect
{
public:
	renderEffect_s parms;
	//renderEffect_s gameParms;
	int gameTime;
	int serviceTime;
	bool newEffect;
	bool expired;
	class rvBSE* effect;
	idBounds referenceBounds;
	float modelMatrix[16];
	class idRenderWorldLocal* world;
	int lastModifiedFrameNum;
	bool archived;
	int viewCount;
	//viewEffect_s* viewEffect;
	int visibleCount;
	//areaReference_s* effectRefs;
	//cullLink_t* cullLinks;
	bool remove;
	int updateFramenum;
	idLinkList<rvRenderEffectLocal> node;
	int index;
	idRenderModel* dynamicModel;
	int dynamicModelFrameCount;
};
// RAVEN END

class idRenderWorld {
public:
	virtual					~idRenderWorld( void ) {};

	// The same render world can be reinitialized as often as desired
	// a NULL or empty mapName will create an empty, single area world
	virtual bool			InitFromMap( const char *mapName ) = 0;

// RAVEN BEGIN
// mwhitlock: Dynamic memory consolidation
#if defined(_RV_MEM_SYS_SUPPORT)
	virtual void			Flush( void ) = 0;
#endif
// RAVEN END

	//-------------- Entity and Light Defs -----------------

	// entityDefs and lightDefs are added to a given world to determine
	// what will be drawn for a rendered scene.  Most update work is defered
	// until it is determined that it is actually needed for a given view.
	virtual	qhandle_t		AddEntityDef( const renderEntity_t *re ) = 0;
	virtual	void			UpdateEntityDef( qhandle_t entityHandle, const renderEntity_t *re ) = 0;
	virtual	void			FreeEntityDef( qhandle_t entityHandle ) = 0;
	virtual const renderEntity_t *GetRenderEntity( qhandle_t entityHandle ) const = 0;

	virtual	qhandle_t		AddLightDef( const renderLight_t *rlight ) = 0;
	virtual	void			UpdateLightDef( qhandle_t lightHandle, const renderLight_t *rlight ) = 0;
	virtual	void			FreeLightDef( qhandle_t lightHandle ) = 0;
	virtual const renderLight_t *GetRenderLight( qhandle_t lightHandle ) const = 0;
// RAVEN BEGIN
	virtual void			WriteRenderLight( idDemoFile *writeDemo, const renderLight_t *light ) = 0;
	virtual void			ReadRenderLight( idDemoFile *readDemo, renderLight_t &light ) = 0;

// jscott: handling of effects
	virtual qhandle_t		AddEffectDef( const renderEffect_t *reffect, int time ) = 0;
	virtual bool			UpdateEffectDef( qhandle_t effectHandle, const renderEffect_t *reffect, int time ) = 0;
	virtual void			StopEffectDef( qhandle_t effectHandle ) = 0;
	virtual const class rvRenderEffectLocal* GetEffectDef( qhandle_t effectHandle ) const = 0;
	virtual void			FreeEffectDef( qhandle_t effectHandle ) = 0;
	virtual bool			EffectDefHasSound( const renderEffect_s *reffect ) = 0;

// jscott: for optimised pushes
	virtual void			PushMarkedDefs( void ) = 0;
	virtual void			ClearMarkedDefs( void ) = 0;
	virtual void			FreeDefs( void ) = 0;

// jscott: fix for FreeWorld crash
	virtual void			RemoveAllModelReferences( idRenderModel *model ) = 0;

// mwhitlock: Xenon texture streaming
#if defined(_XENON)
	virtual void			StreamAreaTextures(bool inBackground) = 0;	
	virtual void			ClearAreaTextureStreamer(void) = 0;
#endif
// RAVEN END

	// Force the generation of all light / surface interactions at the start of a level
	// If this isn't called, they will all be dynamically generated
	virtual	void			GenerateAllInteractions( void ) = 0;

	//-------------- Decals and Overlays  -----------------

	// Creates decals on all world surfaces that the winding projects onto.
	// The projection origin should be infront of the winding plane.
	// The decals are projected onto world geometry between the winding plane and the projection origin.
	// The decals are depth faded from the winding plane to a certain distance infront of the
	// winding plane and the same distance from the projection origin towards the winding.
	virtual void			ProjectDecalOntoWorld( const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) = 0;

	// Creates decals on static models.
	virtual void			ProjectDecal( qhandle_t entityHandle, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) = 0;

	// Creates overlays on dynamic models.
	virtual void			ProjectOverlay( qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material ) = 0;

	// Removes all decals and overlays from the given entity def.
	virtual void			RemoveDecals( qhandle_t entityHandle ) = 0;

	//-------------- Scene Rendering -----------------

	// some calls to material functions use the current renderview time when servicing cinematics.  this function
	// ensures that any parms accessed (such as time) are properly set.
	virtual void			SetRenderView( const renderView_t *renderView ) = 0;

	// rendering a scene may actually render multiple subviews for mirrors and portals, and
	// may render composite textures for gui console screens and light projections
	// It would also be acceptable to render a scene multiple times, for "rear view mirrors", etc
// RAVEN BEGIN
// AReis: Modified RenderScene() signature to include renderFlags variable.
	virtual void			RenderScene( const renderView_t *renderView, int renderFlags = RF_NORMAL ) = 0;
// jscott: for portal skies
	virtual bool			HasSkybox( int areaNum ) = 0;
	virtual void			FindVisibleAreas( idVec3 origin, int areaNum, bool *visibleAreas ) = 0;
// AReis: This is where we draw the portal fadeout polygon
	virtual void			RenderPortalFades( void ) = 0;
// ddynerman: Helper function
	//virtual idVec3			WorldToScreen( renderView_t* view, idVec3 point ) = 0;
	//virtual idBounds		WorldToScreen( renderView_t* view, idBounds bounds ) = 0;
// RAVEN END

	//-------------- Portal Area Information -----------------

	// returns the number of portals
	virtual int				NumPortals( void ) const = 0;

	// returns 0 if no portal contacts the bounds
	// This is used by the game to identify portals that are contained
	// inside doors, so the connection between areas can be topologically
	// terminated when the door shuts.
	virtual	qhandle_t		FindPortal( const idBounds &b ) const = 0;

	// doors explicitly close off portals when shut
	// multiple bits can be set to block multiple things, ie: ( PS_VIEW | PS_LOCATION | PS_AIR )
	virtual	void			SetPortalState( qhandle_t portal, int blockingBits ) = 0;
	virtual int				GetPortalState( qhandle_t portal ) = 0;

	// returns true only if a chain of portals without the given connection bits set
	// exists between the two areas (a door doesn't separate them, etc)
	virtual	bool			AreasAreConnected( int areaNum1, int areaNum2, portalConnection_t connection ) = 0;

	// returns the number of portal areas in a map, so game code can build information
	// tables for the different areas
	virtual	int				NumAreas( void ) const = 0;

	// Will return -1 if the point is not in an area, otherwise
	// it will return 0 <= value < NumAreas()
	virtual int				PointInArea( const idVec3 &point ) const = 0;

	// fills the *areas array with the numbers of the areas the bounds cover
	// returns the total number of areas the bounds cover
	virtual int				BoundsInAreas( const idBounds &bounds, int *areas, int maxAreas ) const = 0;

	// Used by the sound system to do area flowing
	virtual	int				NumPortalsInArea( int areaNum ) = 0;

	// returns one portal from an area
	//virtual void			GetPortals( int areaNum, exitPortal_t *ret, int size ) = 0;
	//virtual void			GetPortal( int areaNum, int portalNum, exitPortal_t *ret ) = 0;
	virtual exitPortal_t	GetPortal( int areaNum, int portalNum ) = 0;

	//-------------- Tracing  -----------------

	// Checks a ray trace against any gui surfaces in an entity, returning the
	// fraction location of the trace on the gui surface, or -1,-1 if no hit.
	// This doesn't do any occlusion testing, simply ignoring non-gui surfaces.
	// start / end are in global world coordinates.
	virtual guiPoint_t		GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const = 0;

	// Traces vs the render model, possibly instantiating a dynamic version, and returns true if something was hit
	virtual bool			ModelTrace( modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius ) const = 0;

	// Traces vs the whole rendered world. FIXME: we need some kind of material flags.
	virtual bool			Trace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic = true, bool skipPlayer = false ) const = 0;

	// Traces vs the world model bsp tree.
	virtual bool			FastWorldTrace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;

	//-------------- Demo Control  -----------------

	// Writes a loadmap command to the demo, and clears archive counters.
	virtual void			StartWritingDemo( idDemoFile *demo ) = 0;
	virtual void			StopWritingDemo( void ) = 0;

	// Returns true when demoRenderView has been filled in.
	// adds/updates/frees entityDefs and lightDefs based on the current demo file
	// and returns the renderView to be used to render this frame.
	// a demo file may need to be advanced multiple times if the framerate
	// is less than 30hz
	// demoTimeOffset will be set if a new map load command was processed before
	// the next renderScene
	virtual bool			ProcessDemoCommand( idDemoFile *readDemo, renderView_t *demoRenderView, int *demoTimeOffset ) = 0;

	// this is used to regenerate all interactions ( which is currently only done during influences ), there may be a less 
	// expensive way to do it
	virtual void			RegenerateWorld( void ) = 0;

	//-------------- Debug Visualization  -----------------

	// Line drawing for debug visualization
	virtual void			DebugClear(int time) = 0;		// a time of 0 will clear all lines and text
	virtual void			DebugLine(const idVec4& color, const idVec3& start, const idVec3& end, const int lifetime = 0, const bool depthTest = false) { }
	virtual void			DebugArrow( const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime = 0 ) = 0;
	virtual void			DebugWinding( const idVec4 &color, const idWinding &w, const idVec3 &origin, const idMat3 &axis, const int lifetime = 0, const bool depthTest = false ) = 0;
	virtual void			DebugCircle( const idVec4 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const int lifetime = 0, const bool depthTest = false ) = 0;
	virtual void			DebugSphere( const idVec4 &color, const idSphere &sphere, const int lifetime = 0, bool depthTest = false ) = 0;
// RAVEN BEGIN
// jscott: want to be able to specify depth test
	virtual void			DebugBounds(const idVec4& color, const idBounds& bounds, const idVec3& org = vec3_origin, const int lifetime = 0, bool depthTest = false) {
		DebugBox(color, idBox(bounds) + org, lifetime);
	}
//	virtual size_t			MemorySummary( const idCmdArgs &args ) = 0;
//	virtual void			ShowDebugLines( void ) = 0;
//	virtual void			ShowDebugPolygons( void ) = 0;
//	virtual void			ShowDebugText( void ) = 0;
// cdr: added debug FOV
	virtual void			DebugFOV(const idVec4& color, const idVec3& origin, const idVec3& dir, float farDot, float farDist, float nearDot = 1.0f, float nearDist = 0.0f, float alpha = 0.3f, int lifetime = 0) { }
// RAVEN END
	virtual void			DebugBox( const idVec4 &color, const idBox &box, const int lifetime = 0 ) = 0;
	virtual void			DebugFrustum( const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin = false, const int lifetime = 0 ) = 0;
	virtual void			DebugCone( const idVec4 &color, const idVec3 &apex, const idVec3 &dir, float radius1, float radius2, const int lifetime = 0 ) = 0;
	virtual void			DebugAxis( const idVec3 &origin, const idMat3 &axis ) = 0;

	// Polygon drawing for debug visualization.
	virtual void			DebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime = 0, const bool depthTest = false ) = 0;

	// Text drawing for debug visualization.
	virtual void			DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align = 1, const int lifetime = 0, bool depthTest = false ) = 0;
};

#endif /* !__RENDERWORLD_H__ */
