/*
Copyright (C) 1999-2007 id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.

This file is part of GtkRadiant.

GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#define LIGHT_SHADOWS_C

#include "light.h"
#include "inout.h"



/* -------------------------------------------------------------------------------

ydnar: this code deals with shadow volume bsps

------------------------------------------------------------------------------- */

typedef struct shadowNode_s
{
	vec4_t	plane;
	int		children[ 2 ];
}
shadowNode_t;

int				numShadowNodes;
shadowNode_t	*shadowNodes;



/*
AddShadow()
adds a shadow, returning the index into the shadow list
*/



/*
MakeShadowFromPoints()
creates a shadow volume from 4 points (the first being the light origin)
*/



/*
SetupShadows()
sets up the shadow volumes for all lights in the world
*/

void SetupShadows( void )
{
	int				i, j, s;
	light_t			*light;
	dleaf_t			*leaf;
	dsurface_t		*ds;
	surfaceInfo_t	*info;
	shaderInfo_t	*si;
	byte			*tested;

	
	/* early out for weird cases where there are no lights */
	if( lights == NULL )
		return;
	
	/* note it */
	Sys_FPrintf( SYS_VRB, "--- SetupShadows ---\n" );
	
	/* allocate a surface test list */
	tested = safe_malloc( numDrawSurfaces / 8 + 1 );
	
	/* walk the list of lights */
	for( light = lights; light != NULL; light = light->next )
	{
		/* do some early out testing */
		if( light->cluster < 0 )
			continue;
		
		/* clear surfacetest list */
		memset( tested, 0, numDrawSurfaces / 8 + 1 );
		
		/* walk the bsp leaves */
		for( i = 0, leaf = dleafs; i < numleafs; i++, leaf++ )
		{
			/* in pvs? */
			if( ClusterVisible( light->cluster, leaf->cluster ) == qfalse )
				continue;
			
			/* walk the surface list for this leaf */
			for( j = 0; j < leaf->numLeafSurfaces; j++ )
			{
				/* don't filter a surface more than once */
				s = dleafsurfaces[ leaf->firstLeafSurface + j ];
				if( tested[ s >> 3 ] & (1 << (s & 7)) )
					continue;
				tested[ s >> 3 ] |= (1 << (s & 7));
				
				/* get surface and info */
				ds = &drawSurfaces[ s ];
				info = &surfaceInfos[ s ];
				si = info->si;
				
				/* don't create shadow volumes from translucent surfaces */
				if( si->contents & CONTENTS_TRANSLUCENT )
					continue;
			}
		}
	}
}
