void map::apply_light_arc(int x, int y, int angle, float luminance, int wideangle ) { if (luminance <= LIGHT_SOURCE_LOCAL) { return; } static bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y]; memset(lit, 0, sizeof(lit)); #define lum_mult 3.0 luminance = luminance * lum_mult; int range = LIGHT_RANGE(luminance); apply_light_source(x, y, LIGHT_SOURCE_LOCAL, trigdist); // Normalise (should work with negative values too) const double PI = 3.14159265358979f; const double HALFPI = 1.570796326794895f; const double wangle = wideangle / 2.0; int nangle = angle % 360; int endx, endy; double rad = PI * (double)nangle / 180; calc_ray_end(nangle, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, trigdist); int testx, testy; calc_ray_end(wangle + nangle, range, x, y, &testx, &testy); double wdist = sqrt(double((endx - testx) * (endx - testx) + (endy - testy) * (endy - testy))); if(wdist > 0.5) { double wstep = ( wangle / ( wdist * 1.42 ) ); // attempt to determine beam density required to cover all squares for (double ao = wstep; ao <= wangle; ao += wstep) { if ( trigdist ) { double fdist = (ao * HALFPI) / wangle; double orad = ( PI * ao / 180.0 ); endx = int( x + ( (double)range - fdist * 2.0) * cos(rad + orad) ); endy = int( y + ( (double)range - fdist * 2.0) * sin(rad + orad) ); apply_light_ray(lit, x, y, endx, endy , luminance, true); endx = int( x + ( (double)range - fdist * 2.0) * cos(rad - orad) ); endy = int( y + ( (double)range - fdist * 2.0) * sin(rad - orad) ); apply_light_ray(lit, x, y, endx, endy , luminance, true); } else { calc_ray_end(nangle + ao, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, false); calc_ray_end(nangle - ao, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, false); } } } }
void map::apply_light_arc(int x, int y, int angle, float luminance, int wideangle ) { if (luminance <= LIGHT_SOURCE_LOCAL) { return; } bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {}; constexpr float lum_mult = 3.0f; luminance = luminance * lum_mult; int range = LIGHT_RANGE(luminance); apply_light_source(x, y, LIGHT_SOURCE_LOCAL, trigdist); // Normalise (should work with negative values too) const double wangle = wideangle / 2.0; int nangle = angle % 360; int endx, endy; double rad = PI * (double)nangle / 180; calc_ray_end(nangle, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, trigdist); int testx, testy; calc_ray_end(wangle + nangle, range, x, y, &testx, &testy); const float wdist = hypot(endx - testx, endy - testy); if (wdist <= 0.5) { return; } // attempt to determine beam density required to cover all squares const double wstep = ( wangle / ( wdist * SQRT_2 ) ); for (double ao = wstep; ao <= wangle; ao += wstep) { if ( trigdist ) { double fdist = (ao * HALFPI) / wangle; double orad = ( PI * ao / 180.0 ); endx = int( x + ( (double)range - fdist * 2.0) * cos(rad + orad) ); endy = int( y + ( (double)range - fdist * 2.0) * sin(rad + orad) ); apply_light_ray(lit, x, y, endx, endy , luminance, true); endx = int( x + ( (double)range - fdist * 2.0) * cos(rad - orad) ); endy = int( y + ( (double)range - fdist * 2.0) * sin(rad - orad) ); apply_light_ray(lit, x, y, endx, endy , luminance, true); } else { calc_ray_end(nangle + ao, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, false); calc_ray_end(nangle - ao, range, x, y, &endx, &endy); apply_light_ray(lit, x, y, endx, endy , luminance, false); } } }
void map::apply_light_arc( const tripoint &p, int angle, float luminance, int wideangle ) { if (luminance <= LIGHT_SOURCE_LOCAL) { return; } bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {}; apply_light_source( p, LIGHT_SOURCE_LOCAL ); // Normalise (should work with negative values too) const double wangle = wideangle / 2.0; int nangle = angle % 360; tripoint end; double rad = PI * (double)nangle / 180; int range = LIGHT_RANGE(luminance); calc_ray_end( nangle, range, p, end ); apply_light_ray(lit, p, end , luminance); tripoint test; calc_ray_end(wangle + nangle, range, p, test ); const float wdist = hypot( end.x - test.x, end.y - test.y ); if (wdist <= 0.5) { return; } // attempt to determine beam density required to cover all squares const double wstep = ( wangle / ( wdist * SQRT_2 ) ); for( double ao = wstep; ao <= wangle; ao += wstep ) { if( trigdist ) { double fdist = (ao * HALFPI) / wangle; double orad = ( PI * ao / 180.0 ); end.x = int( p.x + ( (double)range - fdist * 2.0) * cos(rad + orad) ); end.y = int( p.y + ( (double)range - fdist * 2.0) * sin(rad + orad) ); apply_light_ray( lit, p, end, luminance ); end.x = int( p.x + ( (double)range - fdist * 2.0) * cos(rad - orad) ); end.y = int( p.y + ( (double)range - fdist * 2.0) * sin(rad - orad) ); apply_light_ray( lit, p, end, luminance ); } else { calc_ray_end( nangle + ao, range, p, end ); apply_light_ray( lit, p, end, luminance ); calc_ray_end( nangle - ao, range, p, end ); apply_light_ray( lit, p, end, luminance ); } } }