Пример #1
0
void SplineTrack::merge(IMeshBufferPtr buf) const
{
   Vector<float> off = make_vector(
      static_cast<float>(origin.x),
      height,
      static_cast<float>(origin.y));

   buf->merge(rail_buf, off, 0.0f);

   // Draw the sleepers

   const float sleeper_sep = 0.25f;

   float delta = 0;
   int n = 0;
   do {
      ++n;
      delta = ((curve.length - sleeper_sep) / n) - sleeper_sep;
   } while (delta > sleeper_sep / n);

   for (int i = 0; i <= n; i++) {
      float pos = (sleeper_sep / 2) + i * (sleeper_sep + delta);

      float u_curve_delta;
      Vector<float> v = curve.linear(pos / curve.length, &u_curve_delta);

      const Vector<float> deriv = curve.deriv(u_curve_delta);
      const float angle =
         rad_to_deg<float>(atanf(deriv.z / deriv.x));

      merge_sleeper(buf, off + v, -angle);
   }
}
Пример #2
0
void SlopeTrack::merge(IMeshBufferPtr buf) const
{
   Vector<float> off = make_vector(
      static_cast<float>(origin.x),
      height,
      static_cast<float>(origin.y));

   float y_angle = axis == axis::Y ? -90.0f : 0.0f;

   off += rotateY(make_vector(-0.5f, 0.0f, 0.0f), y_angle);

   buf->merge(rail_buf, off, y_angle);

   // Draw the sleepers
   for (float t = 0.1f; t < 1.0f; t += 0.25f) {
      float u_curve_value;
      const Vector<float> curve_value = curve.linear(t, &u_curve_value);

#if 0
      // Should the sleepers be at the same angle as the slope?
      const Vector<float> deriv = curve.deriv(u_curve_value);
      const float angle =
         rad_to_deg<float>(atanf(deriv.y / deriv.x));
#endif

      Vector<float> v = make_vector(curve_value.x, curve_value.y, 0.0f);

      merge_sleeper(buf, off + rotateY(v, y_angle), y_angle);
   }
}
Пример #3
0
void SlopeTrack::transform(const track::TravelToken& token, float delta) const
{
   assert(delta < length && delta >= 0.0f);

#if 0
   debug() << "f(0)=" << curve(0.0f)
           << " f(0.5)=" << curve(0.5f)
           << " f(1.0)=" << curve(1.0f);

   debug() << "f'(0)=" << curve.deriv(0.0f)
           << " f'(0.5)=" << curve.deriv(0.5f)
           << " f'(1.0)=" << curve.deriv(1.0f);
#endif

   if (token.direction == -axis)
      delta = length - delta;

   const float curve_delta = delta / length;

   float u_curve_delta;
   const Vector<float> curve_value = curve.linear(curve_delta, &u_curve_delta);

   const float x_trans = axis == axis::X ? curve_value.x : 0.0f;
   const float y_trans =curve_value.y;
   const float z_trans = axis == axis::Y ? curve_value.x : 0.0f;

   glTranslated(static_cast<double>(origin.x) + x_trans,
      height + y_trans,
      static_cast<double>(origin.y) + z_trans);

   if (axis == axis::Y)
      glRotated(-90.0, 0.0, 1.0, 0.0);

   glTranslated(-0.5, 0.0, 0.0);

   if (token.direction == -axis)
      glRotated(-180.0, 0.0, 1.0, 0.0);

   const Vector<float> deriv = curve.deriv(u_curve_delta);
   const float angle =
      rad_to_deg<float>(atanf(deriv.y / deriv.x));

   if (token.direction == -axis)
      glRotatef(-angle, 0.0f, 0.0f, 1.0f);
   else
      glRotatef(angle, 0.0f, 0.0f, 1.0f);
}
Пример #4
0
float SlopeTrack::gradient(const track::TravelToken& token, float delta) const
{
   assert(delta < length && delta >= 0.0f);

   if (token.direction == -axis)
      delta = length - delta;

   return curve.deriv(delta / length).y;
}
Пример #5
0
float SplineTrack::rotation_at(float curve_delta) const
{
   assert(curve_delta >= 0.0f && curve_delta <= 1.0f);

   const Vector<float> deriv = curve.deriv(curve_delta);

   // Derivation of angle depends on quadrant
   if (deriv.z >= 0 && deriv.x > 0)
      return rad_to_deg<float>(atanf(deriv.z / deriv.x));
   else if (deriv.z > 0 && deriv.x <= 0)
      return 90 - rad_to_deg<float>(atanf(deriv.x / deriv.z));
   else if (deriv.z <= 0 && deriv.x <= 0)
      return 270 - rad_to_deg<float>(atanf(deriv.x / deriv.z));
   else if (deriv.z <= 0 && deriv.x > 0)
      return rad_to_deg<float>(atanf(deriv.z / deriv.x));
   else
      assert(false);
}
Пример #6
0
void Points::transform(const track::TravelToken& a_token, float delta) const
{
   const float len = segment_length(a_token);

   assert(delta < len);

   if (myX == a_token.position.x && myY == a_token.position.y
      && state == NOT_TAKEN) {

      if (a_token.direction == my_axis
         && (my_axis == -axis::X || my_axis == -axis::Y))
         delta -= 1.0f;

      const float x_trans =
         my_axis == axis::X ? delta
         : (my_axis == -axis::X ? -delta : 0.0f);
      const float y_trans =
         my_axis == axis::Y ? delta
         : (my_axis == -axis::Y ? -delta : 0.0f);

      glTranslatef(static_cast<float>(myX) + x_trans,
         height,
         static_cast<float>(myY) + y_trans);

      if (my_axis == axis::Y || my_axis == -axis::Y)
         glRotated(-90.0, 0.0, 1.0, 0.0);

      glTranslated(-0.5, 0.0, 0.0);
   }
   else if (a_token.position == straight_endpoint()) {
      delta = 2.0f - delta;

      if (a_token.direction == -my_axis
         && (my_axis == axis::X || my_axis == axis::Y))
         delta += 1.0f;

      const float x_trans =
         my_axis == axis::X ? delta
         : (my_axis == -axis::X ? -delta : 0.0f);
      const float y_trans =
         my_axis == axis::Y ? delta
         : (my_axis == -axis::Y ? -delta : 0.0f);

      glTranslatef(static_cast<float>(myX) + x_trans,
         height,
         static_cast<float>(myY) + y_trans);

      if (my_axis == axis::Y || my_axis == -axis::Y)
         glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);

      glTranslatef(-0.5f, 0.0f, 0.0f);
   }
   else if (a_token.position == displaced_endpoint() || state == TAKEN) {
      // Curving onto the straight section
      float x_trans, y_trans, rotate;

      // We have a slight problem in that the domain of the curve
      // function is [0,1] but the delta is in [0,len] so we have
      // to compress the delta into [0,1] here
      const float curve_delta = delta / len;

      bool backwards = a_token.position == displaced_endpoint();

      const float f_value = backwards ? 1.0f - curve_delta : curve_delta;
      float u_f_value;
      const VectorF curve_value = my_curve.linear(f_value, &u_f_value);

      // Calculate the angle that the tangent to the curve at this
      // point makes to (one of) the axis at this point
      const VectorF deriv = my_curve.deriv(u_f_value);
      const float angle =
         rad_to_deg<float>(atanf(deriv.z / deriv.x));

      if (my_axis == -axis::X) {
         x_trans = 1.0f - curve_value.x;
         y_trans = reflected ? curve_value.z : -curve_value.z;
         rotate = reflected ? angle : -angle;
      }
      else if (my_axis == axis::X) {
         x_trans = curve_value.x;
         y_trans = reflected ? -curve_value.z : curve_value.z;
         rotate = reflected ? angle : -angle;
      }
      else if (my_axis == -axis::Y) {
         x_trans = reflected ? -curve_value.z : curve_value.z;
         y_trans = 1.0f - curve_value.x;
         rotate = reflected ? angle : -angle;
      }
      else if (my_axis == axis::Y) {
         x_trans = reflected ? curve_value.z: -curve_value.z;
         y_trans = curve_value.x;
         rotate = reflected ? angle : -angle;
      }
      else
         assert(false);

      glTranslatef(
         static_cast<float>(myX) + x_trans,
         height,
         static_cast<float>(myY) + y_trans);

      if (my_axis == axis::Y || my_axis == -axis::Y)
         glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);

      glTranslatef(-0.5f, 0.0f, 0.0f);

      glRotatef(rotate, 0.0f, 1.0f, 0.0f);
   }
   else
      assert(false);

   if (a_token.direction == -axis::X || a_token.direction == -axis::Y)
      glRotated(-180.0, 0.0, 1.0, 0.0);
}