Пример #1
0
int main() {
  //! [Own Processor Register]
  LinearInit::Register();
  //! [Own Processor Register]

  MotiveEngine engine;

  //! [Own Processor Create Instance]
  // Move from 10 --> -5 in 100 internal time units.
  const MotiveTarget1f target = motive::CurrentToTarget1f(10, 0, -5, 0, 100);

  // Create the one dimensional motivator of type Linear by passing in
  // LinearInit.
  Motivator1f linear_motivator(LinearInit(), &engine, target);
  //! [Own Processor Create Instance]

  //! [Own Processor Advance Simulation]
  // Advance the simulation one tick at a time by calling engine.AdvanceFrame().
  std::vector<vec2> points;
  points.reserve(target.EndTime() + 1);
  for (MotiveTime t = 0; t <= target.EndTime(); ++t) {
    points.push_back(vec2(static_cast<float>(t), linear_motivator.Value()));
    engine.AdvanceFrame(1);
  }
  printf("\n%s",
         motive::Graph2DPoints(&points[0], static_cast<int>(points.size()))
             .c_str());
  //! [Own Processor Advance Simulation]

  return 0;
}
Пример #2
0
  // TODO: Change to CreateSplineToTarget()
  void SetTarget(MotiveIndex index, const MotiveTarget1f& t) {
    SplineData& d = Data(index);

    // If the first node specifies time=0 or there is no valid data in the
    // interpolator, we want to override the current values with the values
    // specified in the first node.
    const MotiveNode1f& node0 = t.Node(0);
    const bool override_current =
        node0.time == 0 || !interpolator_.Valid(index);
    // TODO(b/65298927):  It seems that the animation pipeline can produce data
    // that is out of range.  Instead of just using node0.value directly, if
    // the interpolator is doing modular arithmetic, normalize the y value to
    // the modulator's range.
    const float start_y =
        override_current
            ? (interpolator_.ModularArithmetic(index)
                   ? interpolator_.ModularRange(index).Normalize(node0.value)
                   : node0.value)
            : interpolator_.NormalizedY(index);
    const float start_derivative =
        override_current ? node0.velocity : Velocity(index);
    const int start_node_index = override_current ? 1 : 0;

    // Ensure we have a local spline available, allocated from our pool of
    // splines.
    if (d.local_spline == nullptr) {
      d.local_spline = AllocateSpline();
    }

    // Initialize the compact spline to hold the sequence of nodes in 't'.
    // Add the first node, which has the start condition.
    const float end_x = static_cast<float>(t.EndTime());
    const Range y_range = CalculateYRange(index, t, start_y);
    const float x_granularity = CompactSpline::RecommendXGranularity(end_x);
    d.local_spline->Init(y_range, x_granularity);
    d.local_spline->AddNode(0.0f, start_y, start_derivative);

    // Add subsequent nodes, in turn, taking care to respect the 'direction'
    // request when using modular arithmetic.
    float prev_y = start_y;
    for (int i = start_node_index; i < t.num_nodes(); ++i) {
      const MotiveNode1f& n = t.Node(i);
      const float y = interpolator_.NextY(index, prev_y, n.value, n.direction);
      d.local_spline->AddNode(static_cast<float>(n.time), y, n.velocity,
                              motive::kAddWithoutModification);
      prev_y = y;
    }

    // Point the interpolator at the spline we just created. Always start our
    // spline at time 0.
    interpolator_.SetSplines(index, 1, d.local_spline, SplinePlayback());
  }