Author: rambetter
[divverent/netradiant.git] / tools / quake3 / q3map2 / light_shadows.c
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #define LIGHT_SHADOWS_C
23
24 #include "light.h"
25 #include "inout.h"
26
27
28
29 /* -------------------------------------------------------------------------------
30
31 ydnar: this code deals with shadow volume bsps
32
33 ------------------------------------------------------------------------------- */
34
35 typedef struct shadowNode_s
36 {
37         vec4_t  plane;
38         int             children[ 2 ];
39 }
40 shadowNode_t;
41
42 int                             numShadowNodes;
43 shadowNode_t    *shadowNodes;
44
45
46
47 /*
48 AddShadow()
49 adds a shadow, returning the index into the shadow list
50 */
51
52
53
54 /*
55 MakeShadowFromPoints()
56 creates a shadow volume from 4 points (the first being the light origin)
57 */
58
59
60
61 /*
62 SetupShadows()
63 sets up the shadow volumes for all lights in the world
64 */
65
66 void SetupShadows( void )
67 {
68         int                             i, j, s;
69         light_t                 *light;
70         dleaf_t                 *leaf;
71         dsurface_t              *ds;
72         surfaceInfo_t   *info;
73         shaderInfo_t    *si;
74         byte                    *tested;
75
76         
77         /* early out for weird cases where there are no lights */
78         if( lights == NULL )
79                 return;
80         
81         /* note it */
82         Sys_FPrintf( SYS_VRB, "--- SetupShadows ---\n" );
83         
84         /* allocate a surface test list */
85         tested = safe_malloc( numDrawSurfaces / 8 + 1 );
86         
87         /* walk the list of lights */
88         for( light = lights; light != NULL; light = light->next )
89         {
90                 /* do some early out testing */
91                 if( light->cluster < 0 )
92                         continue;
93                 
94                 /* clear surfacetest list */
95                 memset( tested, 0, numDrawSurfaces / 8 + 1 );
96                 
97                 /* walk the bsp leaves */
98                 for( i = 0, leaf = dleafs; i < numleafs; i++, leaf++ )
99                 {
100                         /* in pvs? */
101                         if( ClusterVisible( light->cluster, leaf->cluster ) == qfalse )
102                                 continue;
103                         
104                         /* walk the surface list for this leaf */
105                         for( j = 0; j < leaf->numLeafSurfaces; j++ )
106                         {
107                                 /* don't filter a surface more than once */
108                                 s = dleafsurfaces[ leaf->firstLeafSurface + j ];
109                                 if( tested[ s >> 3 ] & (1 << (s & 7)) )
110                                         continue;
111                                 tested[ s >> 3 ] |= (1 << (s & 7));
112                                 
113                                 /* get surface and info */
114                                 ds = &drawSurfaces[ s ];
115                                 info = &surfaceInfos[ s ];
116                                 si = info->si;
117                                 
118                                 /* don't create shadow volumes from translucent surfaces */
119                                 if( si->contents & CONTENTS_TRANSLUCENT )
120                                         continue;
121                         }
122                 }
123         }
124 }