2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 int r_dlightframecount
;
33 void R_AnimateLight (void)
39 // 'm' is normal light, 'a' is no light, 'z' is double bright
40 i
= (int)(cl
.time
*10);
41 for (j
=0 ; j
<MAX_LIGHTSTYLES
; j
++)
43 if (!cl_lightstyle
[j
].length
)
45 d_lightstylevalue
[j
] = 256;
48 k
= i
% cl_lightstyle
[j
].length
;
49 k
= cl_lightstyle
[j
].map
[k
] - 'a';
51 d_lightstylevalue
[j
] = k
;
57 =============================================================================
61 =============================================================================
69 void R_MarkLights (dlight_t
*light
, int bit
, mnode_t
*node
)
76 if (node
->contents
< 0)
79 splitplane
= node
->plane
;
80 dist
= DotProduct (light
->origin
, splitplane
->normal
) - splitplane
->dist
;
82 if (dist
> light
->radius
)
84 R_MarkLights (light
, bit
, node
->children
[0]);
87 if (dist
< -light
->radius
)
89 R_MarkLights (light
, bit
, node
->children
[1]);
94 surf
= cl
.worldmodel
->surfaces
+ node
->firstsurface
;
95 for (i
=0 ; i
<node
->numsurfaces
; i
++, surf
++)
97 if (surf
->dlightframe
!= r_dlightframecount
)
100 surf
->dlightframe
= r_dlightframecount
;
102 surf
->dlightbits
|= bit
;
105 R_MarkLights (light
, bit
, node
->children
[0]);
106 R_MarkLights (light
, bit
, node
->children
[1]);
115 void R_PushDlights (void)
120 r_dlightframecount
= r_framecount
+ 1; // because the count hasn't
121 // advanced yet for this frame
124 for (i
=0 ; i
<MAX_DLIGHTS
; i
++, l
++)
126 if (l
->die
< cl
.time
|| !l
->radius
)
128 R_MarkLights ( l
, 1<<i
, cl
.worldmodel
->nodes
);
134 =============================================================================
138 =============================================================================
141 int RecursiveLightPoint (mnode_t
*node
, vec3_t start
, vec3_t end
)
144 float front
, back
, frac
;
156 if (node
->contents
< 0)
157 return -1; // didn't hit anything
159 // calculate mid point
161 // FIXME: optimize for axial
163 front
= DotProduct (start
, plane
->normal
) - plane
->dist
;
164 back
= DotProduct (end
, plane
->normal
) - plane
->dist
;
167 if ( (back
< 0) == side
)
168 return RecursiveLightPoint (node
->children
[side
], start
, end
);
170 frac
= front
/ (front
-back
);
171 mid
[0] = start
[0] + (end
[0] - start
[0])*frac
;
172 mid
[1] = start
[1] + (end
[1] - start
[1])*frac
;
173 mid
[2] = start
[2] + (end
[2] - start
[2])*frac
;
175 // go down front side
176 r
= RecursiveLightPoint (node
->children
[side
], start
, mid
);
178 return r
; // hit something
180 if ( (back
< 0) == side
)
181 return -1; // didn't hit anuthing
183 // check for impact on this node
185 surf
= cl
.worldmodel
->surfaces
+ node
->firstsurface
;
186 for (i
=0 ; i
<node
->numsurfaces
; i
++, surf
++)
188 if (surf
->flags
& SURF_DRAWTILED
)
189 continue; // no lightmaps
193 s
= DotProduct (mid
, tex
->vecs
[0]) + tex
->vecs
[0][3];
194 t
= DotProduct (mid
, tex
->vecs
[1]) + tex
->vecs
[1][3];;
196 if (s
< surf
->texturemins
[0] ||
197 t
< surf
->texturemins
[1])
200 ds
= s
- surf
->texturemins
[0];
201 dt
= t
- surf
->texturemins
[1];
203 if ( ds
> surf
->extents
[0] || dt
> surf
->extents
[1] )
212 lightmap
= surf
->samples
;
217 lightmap
+= dt
* ((surf
->extents
[0]>>4)+1) + ds
;
219 for (maps
= 0 ; maps
< MAXLIGHTMAPS
&& surf
->styles
[maps
] != 255 ;
222 scale
= d_lightstylevalue
[surf
->styles
[maps
]];
223 r
+= *lightmap
* scale
;
224 lightmap
+= ((surf
->extents
[0]>>4)+1) *
225 ((surf
->extents
[1]>>4)+1);
235 return RecursiveLightPoint (node
->children
[!side
], mid
, end
);
238 int R_LightPoint (vec3_t p
)
243 if (!cl
.worldmodel
->lightdata
)
248 end
[2] = p
[2] - 2048;
250 r
= RecursiveLightPoint (cl
.worldmodel
->nodes
, p
, end
);
255 if (r
< r_refdef
.ambientlight
)
256 r
= r_refdef
.ambientlight
;