thirtyflightsofloving/renderer/r_vlights.c
2020-06-12 12:21:21 -07:00

145 lines
3.5 KiB
C

/*
Copyright (C) 1997-2001 Id Software, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Vic did core of this - THANK YOU KING VIC!!! - psychospaz
#include "r_local.h"
#include "vlights.h"
#define VLIGHT_CLAMP_MIN 50.0f
#define VLIGHT_CLAMP_MAX 256.0f
#define VLIGHT_GRIDSIZE_X 256
#define VLIGHT_GRIDSIZE_Y 256
vec3_t vlightgrid[VLIGHT_GRIDSIZE_X][VLIGHT_GRIDSIZE_Y];
static vec3_t r_avertexnormals[NUMVERTEXNORMALS] = {
#include "anorms.h"
};
void VLight_InitAnormTable (void)
{
int x, y;
float angle;
float sp, sy, cp, cy;
for ( x = 0; x < VLIGHT_GRIDSIZE_X; x++ )
{
angle = (x * 360 / VLIGHT_GRIDSIZE_X) * ( M_PI / 180.0f );
sy = sin(angle);
cy = cos(angle);
for ( y = 0; y < VLIGHT_GRIDSIZE_Y; y++ )
{
angle = (y * 360 / VLIGHT_GRIDSIZE_X) * ( M_PI / 180.0f );
sp = sin(angle);
cp = cos(angle);
vlightgrid[x][y][0] = cp*cy;
vlightgrid[x][y][1] = cp*sy;
vlightgrid[x][y][2] = -sp;
}
}
}
float VLight_GetLightValue ( vec3_t normal, vec3_t dir, float apitch, float ayaw, qboolean dlight )
{
int pitchofs, yawofs;
float angle1, angle2, light;
if ( normal[1] == 0 && normal[0] == 0 )
{
angle2 = 0;
if ( normal[2] > 0 )
angle1 = 90;
else
angle1 = 270;
}
else
{
float forward;
angle2 = atan2( normal[1], normal[0] ) * ( 180.0f / M_PI );
if (angle2 < 0)
angle2 += 360;
forward = sqrt ( normal[0]*normal[0] + normal[1]*normal[1] );
angle1 = atan2( normal[2], forward ) * ( 180.0f / M_PI );
if (angle1 < 0)
angle1 += 360;
}
pitchofs = ( angle1 + apitch ) * VLIGHT_GRIDSIZE_X / 360;
yawofs = ( angle2 + ayaw ) * VLIGHT_GRIDSIZE_Y / 360;
while (pitchofs > (VLIGHT_GRIDSIZE_X-1))
pitchofs -= VLIGHT_GRIDSIZE_X;
while (pitchofs < 0)
pitchofs += VLIGHT_GRIDSIZE_X;
while (yawofs > (VLIGHT_GRIDSIZE_Y-1))
yawofs -= VLIGHT_GRIDSIZE_Y;
while (yawofs < 0)
yawofs += VLIGHT_GRIDSIZE_Y;
if (dlight)
{
light = DotProduct( vlightgrid[pitchofs][yawofs], dir );
if (light>1)
light=1;
if (light<0)
light=0;
return light;
}
else
{
light = ( DotProduct( vlightgrid[pitchofs][yawofs], dir ) + 2.0f ) * 63.5f;
if (light > VLIGHT_CLAMP_MAX)
light = VLIGHT_CLAMP_MAX;
if (light < VLIGHT_CLAMP_MIN)
light = VLIGHT_CLAMP_MIN;
return light * ( 1.0f / 256.0f );
}
}
float VLight_LerpLight ( int index1, int index2, float ilerp, vec3_t dir, vec3_t angles, qboolean dlight )
{
vec3_t normal;
normal[0] = r_avertexnormals[index1][0] + ( r_avertexnormals[index2][0] - r_avertexnormals[index1][0] ) * ilerp;
normal[1] = r_avertexnormals[index1][1] + ( r_avertexnormals[index2][1] - r_avertexnormals[index1][1] ) * ilerp;
normal[2] = r_avertexnormals[index1][2] + ( r_avertexnormals[index2][2] - r_avertexnormals[index1][2] ) * ilerp;
VectorNormalize ( normal );
return VLight_GetLightValue( normal, dir, angles[PITCH], angles[YAW], dlight );
}
void VLight_Init (void)
{
VLight_InitAnormTable ();
}