virtual void SetUp() { short_spline_.Init(Range(0.0f, 1.0f), 0.01f); short_spline_.AddNode(0.0f, 0.1f, 0.0f, motive::kAddWithoutModification); short_spline_.AddNode(1.0f, 0.4f, 0.0f, motive::kAddWithoutModification); short_spline_.AddNode(4.0f, 0.2f, 0.0f, motive::kAddWithoutModification); short_spline_.AddNode(40.0f, 0.2f, 0.0f, motive::kAddWithoutModification); short_spline_.AddNode(100.0f, 1.0f, 0.0f, motive::kAddWithoutModification); }
int main() { // Since we use the ‘smooth’ animation algorithm, we must register it. motive::SmoothInit::Register(); // The engine is the central place for animation data. motive::MotiveEngine engine; // In this example, we animate a one-dimensional floating point value. motive::Motivator1f facing_angle; // Initialize facing_angle Motivator to animate as a 'Smooth' Motivator. // Alternatively, we could initialize as an 'Overshoot' Motivator. All // Motivator types have the same interface. Internally, they are animated // with different algorithms, and they will move differently towards their // targets. However, to switch between Motivator types it is a simple matter // of initializing with a different kind of MotiveInit struct. // // Angles wrap around with modular arithmetic. That is, -pi is equivalent to // pi. Valid range for angles is -pi..pi, inclusive of +pi and exclusive of // -pi. const motive::SmoothInit init(Range(-kPi, kPi), true); facing_angle.Initialize(init, &engine); // Set initial state of the Motivator, and the target parameters. // 'Smooth' Motivators animate to a target-value in a target-time. Not all // types of Motivators use all target data. const Angle start = Angle::FromDegrees(120.0f); const float start_angular_velocity = 0.0f; const Angle target = Angle::FromDegrees(-120.0f); const float target_angular_velocity = 0.0f; const motive::MotiveTime target_time = 100; const motive::MotiveTime delta_time = 1; facing_angle.SetTarget( motive::CurrentToTarget1f(start.ToRadians(), start_angular_velocity, target.ToRadians(), target_angular_velocity, target_time)); std::vector<vec2> points(target_time / delta_time + 1); for (motive::MotiveTime t = 0; t <= target_time; t += delta_time) { // All Motivators created with 'engine' are animated here. engine.AdvanceFrame(delta_time); // The current value of the variable being animated is always available. const Angle angle_at_t = Angle::FromWithinThreePi(facing_angle.Value()); points.push_back( vec2(static_cast<float>(t), angle_at_t.ToDegrees())); } printf("\n%s", Graph2DPoints(&points[0], points.size()).c_str()); return 0; }
// Take an array of SplineNodes (x, y, derivative) values and scale them // to create a CompactSpline. We use Dual Cubic interpolation to ensure that // the splines are well behaved. static void CreateSpline(const SplineNode* nodes, size_t num_nodes, float x_scale, float y_scale, CompactSpline* spline) { // Find y-extremes. float min = std::numeric_limits<float>::infinity(); float max = -std::numeric_limits<float>::infinity(); for (size_t i = 0; i < num_nodes; ++i) { min = std::min(nodes[i].y, min); max = std::max(nodes[i].y, max); } // Initialize the spline such that it's bounds are tight to the data. spline->Init( Range(y_scale * min, y_scale * max), CompactSpline::RecommendXGranularity(x_scale * nodes[num_nodes - 1].x)); // Scale each node and add it to the curve. for (size_t i = 0; i < num_nodes; ++i) { const SplineNode& n = nodes[i]; spline->AddNode(n.x * x_scale, n.y * y_scale, n.derivative / x_scale); } }
using motive::CubicCurve; using motive::CubicInit; using motive::kPi; using motive::kTwoPi; using motive::QuadraticCurve; using motive::Range; using motive::SplinePlayback; using mathfu::vec2; using mathfu::vec2i; using motive::MotiveEngine; using motive::MatrixInit; using motive::MatrixOpArray; using motive::MatrixMotivator4f; using motive::SplineInit; static const SplineInit kRotateInit(Range(-kPi, kPi), true); static const SplineInit kTranslateInit(Range(-1.0f, 1.0f), true); static const int kNumBenchmarkIds = 10; struct SplineNode { float x; float y; float derivative; }; static const SplineNode kSinWave[] = {{0.0f, 0.0f, 1.0f}, {0.5f * kPi, 1.0f, 0.0f}, {kPi, 0.0f, -1.0f}, {1.5f * kPi, -1.0f, 0.0f}, {kTwoPi, 0.0f, 1.0f}};