packages/flip-toolkit/src/forked-rebound/Spring.js
/**
   * The main solver method for the Spring. It takes
   * the current time and delta since the last time step and performs
   * an RK4 integration to get the new position and velocity state
   * for the Spring based on the tension, friction, velocity, and
   * displacement of the Spring.
   * @public
   */
The main solver method for the Spring. It takes
the current time and delta since the last time step and performs
an RK4 integration to get the new position and velocity state
for the Spring based on the tension, friction, velocity, and
displacement of the Spring.
@public
The main solver method for the Spring . It takes the current time and delta since the last time step and performs an RK4 integration to get the new position and velocity state for the Spring based on the tension friction velocity and displacement of the Spring . @public
advance(time, realDeltaTime) {
    let isAtRest = this.isAtRest()
    if (isAtRest && this._wasAtRest) {
      return
    }
    let adjustedDeltaTime = realDeltaTime
    if (realDeltaTime > MAX_DELTA_TIME_SEC) {
      adjustedDeltaTime = MAX_DELTA_TIME_SEC
    }
    this._timeAccumulator += adjustedDeltaTime
    const tension = this._springConfig.tension
    const friction = this._springConfig.friction
    let position = this._currentState.position
    let velocity = this._currentState.velocity
    let tempPosition = this._tempState.position
    let tempVelocity = this._tempState.velocity
    let aVelocity
    let aAcceleration
    let bVelocity
    let bAcceleration
    let cVelocity
    let cAcceleration
    let dVelocity
    let dAcceleration
    let dxdt
    let dvdt
    while (this._timeAccumulator >= SOLVER_TIMESTEP_SEC) {
      this._timeAccumulator -= SOLVER_TIMESTEP_SEC
      if (this._timeAccumulator < SOLVER_TIMESTEP_SEC) {
        this._previousState.position = position
        this._previousState.velocity = velocity
      }
      aVelocity = velocity
      aAcceleration =
        tension * (this._endValue - tempPosition) - friction * velocity
      tempPosition = position + aVelocity * SOLVER_TIMESTEP_SEC * 0.5
      tempVelocity = velocity + aAcceleration * SOLVER_TIMESTEP_SEC * 0.5
      bVelocity = tempVelocity
      bAcceleration =
        tension * (this._endValue - tempPosition) - friction * tempVelocity
      tempPosition = position + bVelocity * SOLVER_TIMESTEP_SEC * 0.5
      tempVelocity = velocity + bAcceleration * SOLVER_TIMESTEP_SEC * 0.5
      cVelocity = tempVelocity
      cAcceleration =
        tension * (this._endValue - tempPosition) - friction * tempVelocity
      tempPosition = position + cVelocity * SOLVER_TIMESTEP_SEC
      tempVelocity = velocity + cAcceleration * SOLVER_TIMESTEP_SEC
      dVelocity = tempVelocity
      dAcceleration =
        tension * (this._endValue - tempPosition) - friction * tempVelocity
      dxdt =
        (1.0 / 6.0) * (aVelocity + 2.0 * (bVelocity + cVelocity) + dVelocity)
      dvdt =
        (1.0 / 6.0) *
        (aAcceleration + 2.0 * (bAcceleration + cAcceleration) + dAcceleration)
      position += dxdt * SOLVER_TIMESTEP_SEC
      velocity += dvdt * SOLVER_TIMESTEP_SEC
    }
    this._tempState.position = tempPosition
    this._tempState.velocity = tempVelocity
    this._currentState.position = position
    this._currentState.velocity = velocity
    if (this._timeAccumulator > 0) {
      this._interpolate(this._timeAccumulator / SOLVER_TIMESTEP_SEC)
    }
    if (
      this.isAtRest() ||
      (this._overshootClampingEnabled && this.isOvershooting())
    ) {
      if (this._springConfig.tension > 0) {
        this._startValue = this._endValue
        this._currentState.position = this._endValue
      } else {
        this._endValue = this._currentState.position
        this._startValue = this._endValue
      }
      this.setVelocity(0)
      isAtRest = true
    }
    let notifyActivate = false
    if (this._wasAtRest) {
      this._wasAtRest = false
      notifyActivate = true
    }
    let notifyAtRest = false
    if (isAtRest) {
      this._wasAtRest = true
      notifyAtRest = true
    }
    this.notifyPositionUpdated(notifyActivate, notifyAtRest)
  }
advance ( time , realDeltaTime ) { let isAtRest = this . isAtRest ( ) if ( isAtRest && this . _wasAtRest ) { return } let adjustedDeltaTime = realDeltaTime if ( realDeltaTime > MAX_DELTA_TIME_SEC ) { adjustedDeltaTime = MAX_DELTA_TIME_SEC } this . _timeAccumulator += adjustedDeltaTime const tension = this . _springConfig . tension const friction = this . _springConfig . friction let position = this . _currentState . position let velocity = this . _currentState . velocity let tempPosition = this . _tempState . position let tempVelocity = this . _tempState . velocity let aVelocity let aAcceleration let bVelocity let bAcceleration let cVelocity let cAcceleration let dVelocity let dAcceleration let dxdt let dvdt while ( this . _timeAccumulator >= SOLVER_TIMESTEP_SEC ) { this . _timeAccumulator -= SOLVER_TIMESTEP_SEC if ( this . _timeAccumulator < SOLVER_TIMESTEP_SEC ) { this . _previousState . position = position this . _previousState . velocity = velocity } aVelocity = velocity aAcceleration = tension * ( this . _endValue - tempPosition ) - friction * velocity tempPosition = position + aVelocity * SOLVER_TIMESTEP_SEC * 0.5 tempVelocity = velocity + aAcceleration * SOLVER_TIMESTEP_SEC * 0.5 bVelocity = tempVelocity bAcceleration = tension * ( this . _endValue - tempPosition ) - friction * tempVelocity tempPosition = position + bVelocity * SOLVER_TIMESTEP_SEC * 0.5 tempVelocity = velocity + bAcceleration * SOLVER_TIMESTEP_SEC * 0.5 cVelocity = tempVelocity cAcceleration = tension * ( this . _endValue - tempPosition ) - friction * tempVelocity tempPosition = position + cVelocity * SOLVER_TIMESTEP_SEC tempVelocity = velocity + cAcceleration * SOLVER_TIMESTEP_SEC dVelocity = tempVelocity dAcceleration = tension * ( this . _endValue - tempPosition ) - friction * tempVelocity dxdt = ( 1.0 / 6.0 ) * ( aVelocity + 2.0 * ( bVelocity + cVelocity ) + dVelocity ) dvdt = ( 1.0 / 6.0 ) * ( aAcceleration + 2.0 * ( bAcceleration + cAcceleration ) + dAcceleration ) position += dxdt * SOLVER_TIMESTEP_SEC velocity += dvdt * SOLVER_TIMESTEP_SEC } this . _tempState . position = tempPosition this . _tempState . velocity = tempVelocity this . _currentState . position = position this . _currentState . velocity = velocity if ( this . _timeAccumulator > 0 ) { this . _interpolate ( this . _timeAccumulator / SOLVER_TIMESTEP_SEC ) } if ( this . isAtRest ( ) || ( this . _overshootClampingEnabled && this . isOvershooting ( ) ) ) { if ( this . _springConfig . tension > 0 ) { this . _startValue = this . _endValue this . _currentState . position = this . _endValue } else { this . _endValue = this . _currentState . position this . _startValue = this . _endValue } this . setVelocity ( 0 ) isAtRest = true } let notifyActivate = false if ( this . _wasAtRest ) { this . _wasAtRest = false notifyActivate = true } let notifyAtRest = false if ( isAtRest ) { this . _wasAtRest = true notifyAtRest = true } this . notifyPositionUpdated ( notifyActivate , notifyAtRest ) }
The main solver method for the Spring.
The main solver method for the Spring .