/* 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 (); }