Пример #1
0
void Color::lerp(const Color& c1, const Color& c2, float t)
{
    color_lerp(&c_, &c1.c_, &c2.c_, t);
}
Пример #2
0
// returns true if further calls could possibly result in a mesh
void LightCaster::add_triangle(Mesh* result, const Vector_& light,
                               Wall* last_closest, float beginAngle, float nextAngle) {
  // within our angle bounds?
  float da1 = signed_angular_distance(angle, beginAngle);
  if(da1 > halfwidth) return; // swath begins after our cutoff
  float da2 = signed_angular_distance(angle, nextAngle);
  if(da2 < -halfwidth) return; // swath ends before our cutoff

  // clamp the values we did get
  float ada1 = ABS(da1);
  if(ada1 > halfwidth) {
    float fixup = halfwidth - ada1;
    beginAngle += fixup * sign(da1);
  }

  float ada2 = ABS(da2);
  if(ada2 > halfwidth) {
    float fixup = halfwidth - ada2;
    nextAngle += fixup * sign(da2);
  }


  int steps = ceilf(signed_angular_distance(beginAngle, nextAngle) / max_angle_step);

  float oldBegin = beginAngle;
  float oldNext = nextAngle;

  for(int ii = 0; ii < steps; ++ii) {
    beginAngle = oldBegin + ii * max_angle_step;
    float delta = signed_angular_distance(beginAngle, oldNext);
    nextAngle = beginAngle + MIN(delta, max_angle_step);

    // interset the discovered angle range with the previously
    // closest wall segment
    Vector_ a1;
    a1.x = light.x + cosf(beginAngle);
    a1.y = light.y + sinf(beginAngle);
    Vector_ a2;
    a2.x = light.x + cosf(nextAngle);
    a2.y = light.y + sinf(nextAngle);
    Vector_ i1, i2;
    line_intersection(&i1, &last_closest->start, &last_closest->end, &light, &a1);
    line_intersection(&i2, &last_closest->start, &last_closest->end, &light, &a2);

    Color c1, c2;
    float d1 = vector_dist(&i1, &light);
    float d2 = vector_dist(&i2, &light);
    color_lerp(&c1, &min_color, &max_color, MIN(1.0f, d1 / max_range));
    color_lerp(&c2, &min_color, &max_color, MIN(1.0f, d2 / max_range));

    if(d1 > max_range) {
      vector_direction_scaled(&i1, &i1, &light, max_range);
      vector_add(&i1, &i1, &light);
    }

    if(d2 > max_range) {
      vector_direction_scaled(&i2, &i2, &light, max_range);
      vector_add(&i2, &i2, &light);
    }

    // add a triangle to the mesh
    result->add_point(light, min_color);
    result->add_point(i1, c1);
    result->add_point(i2, c2);
  }
}