Ejemplo n.º 1
0
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);
            }
        }
    }
}
Ejemplo n.º 2
0
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);
        }
    }
}
Ejemplo n.º 3
0
void map::apply_light_source(int x, int y, float luminance, bool trig_brightcalc )
{
 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y];
 memset(lit, 0, sizeof(lit));

 if (INBOUNDS(x, y)) {
  lit[x][y] = true;
  lm[x][y] += std::max(luminance, static_cast<float>(LL_LOW));
  sm[x][y] += luminance;
 }
 if ( luminance <= 1 ) {
   return;
 } else if ( luminance <=2 ) {
   luminance = 1.49f;
 }
/* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
     neighboring fires to the north and west that were applied via light_source_buffer
   If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
   If there's a 100 luminance magnesium flare south added via apply_light_source instead od
     add_light_source, it's unbuffered so we'll still cast rays into sy.

      ey
    nnnNnnn
    w     e
    w  5 +e
 sx W 5*1+E ex
    w ++++e
    w+++++e
    sssSsss
       sy
*/
  const int peer_inbounds = LIGHTMAP_CACHE_X-1;
  bool north=(y != 0 && light_source_buffer[x][y-1] < luminance );
  bool south=(y != peer_inbounds && light_source_buffer[x][y+1] < luminance );
  bool east=(x != peer_inbounds && light_source_buffer[x+1][y] < luminance );
  bool west=(x != 0 && light_source_buffer[x-1][y] < luminance );

 if (luminance > LIGHT_SOURCE_LOCAL) {
  int range = LIGHT_RANGE(luminance);
  int sx = x - range; int ex = x + range;
  int sy = y - range; int ey = y + range;

  for(int off = sx; off <= ex; ++off) {
   if ( south ) apply_light_ray(lit, x, y, off, sy, luminance, trig_brightcalc);
   if ( north ) apply_light_ray(lit, x, y, off, ey, luminance, trig_brightcalc);
  }

  // Skip corners with + 1 and < as they were done
  for(int off = sy + 1; off < ey; ++off) {
   if ( west ) apply_light_ray(lit, x, y, sx, off, luminance, trig_brightcalc);
   if ( east ) apply_light_ray(lit, x, y, ex, off, luminance, trig_brightcalc);
  }
 }
}
Ejemplo n.º 4
0
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 );
        }
    }
}