DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (dcc6d7a0dc00)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_layers_AxisPhysicsModel_h
#define mozilla_layers_AxisPhysicsModel_h

#include "AxisPhysicsModel.h"
#include <sys/types.h>                  // for int32_t
#include "mozilla/TimeStamp.h"          // for TimeDuration

namespace mozilla {
namespace layers {


/**
 * AxisPhysicsModel encapsulates a generic 1-dimensional physically-based motion
 * model.
 *
 * It performs frame-rate independent interpolation and RK4 integration for
 * smooth animation with stable, deterministic behavior.
 * Implementations are expected to subclass and override the Acceleration()
 * method.
 */
class AxisPhysicsModel {
public:
  AxisPhysicsModel(double aInitialPosition, double aInitialVelocity);
  ~AxisPhysicsModel();

  /**
   * Advance the physics simulation.
   * |aDelta| is the time since the last sample.
   */
  void Simulate(const TimeDuration& aDeltaTime);

  /**
   * Gets the raw velocity of this axis at this moment.
   */
  double GetVelocity();

  /**
   * Sets the raw velocity of this axis at this moment.
   */
  void SetVelocity(double aVelocity);

  /**
   * Gets the raw position of this axis at this moment.
   */
  double GetPosition();

  /**
   * Sets the raw position of this axis at this moment.
   */
  void SetPosition(double aPosition);

protected:

  struct State
  {
    State(double ap, double av) : p(ap), v(av) {};
    double p; // Position
    double v; // Velocity
  };

  struct Derivative
  {
    Derivative() : dp(0.0), dv(0.0) {};
    Derivative(double aDp, double aDv) : dp(aDp), dv(aDv) {};
    double dp; // dp / delta time = Position
    double dv; // dv / delta time = Velocity
  };

  /**
   * Acceleration must be overridden and return the number of
   * axis-position-units / second that should be added or removed from the
   * velocity.
   */
  virtual double Acceleration(const State &aState) = 0;

private:

  /**
   * Duration of fixed delta time step (seconds)
   */
  static const double kFixedTimestep;

  /**
   * 0.0 - 1.0 value indicating progress between current and next simulation
   * sample.  Normalized to units of kFixedTimestep duration.
   */
  double mProgress;

  /**
   * Sample of simulation state as it existed
   * (1.0 - mProgress) * kFixedTimestep seconds in the past.
   */
  State mPrevState;

  /**
   * Sample of simulation state as it will be in mProgress * kFixedTimestep
   * seconds in the future.
   */
  State mNextState;

  /**
   * Perform RK4 (Runge-Kutta method) Integration to calculate the next
   * simulation sample.
   */
  void Integrate(double aDeltaTime);

  /**
   * Apply delta velocity and position represented by aDerivative over
   * aDeltaTime seconds, calculate new acceleration, and return new deltas.
   */
  Derivative Evaluate(const State &aInitState, double aDeltaTime,
                      const Derivative &aDerivative);

  /**
   * Helper function for performing linear interpolation (lerp) of double's
   */
  static double LinearInterpolate(double aV1, double aV2, double aBlend);

};


} // namespace layers
} // namespace mozilla

#endif