105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2010 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */ 805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "FlingState.h" 1205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkMatrix.h" 1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkTime.h" 1405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#define DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER true 1605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic const float MAX_FLING_SPEED = 1500; 1805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic float pin_max_fling(float speed) { 2005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (speed > MAX_FLING_SPEED) { 2105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger speed = MAX_FLING_SPEED; 2205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return speed; 2405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 2505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 2605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic double getseconds() { 2705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return SkTime::GetMSecs() * 0.001; 2805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 2905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 3005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// returns +1 or -1, depending on the sign of x 3105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// returns +1 if x is zero 3205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic SkScalar SkScalarSign(SkScalar x) { 3305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkScalar sign = SK_Scalar1; 3405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (x < 0) { 3505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger sign = -sign; 3605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 3705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return sign; 3805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 3905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 4005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void unit_axis_align(SkVector* unit) { 4105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const SkScalar TOLERANCE = SkDoubleToScalar(0.15); 4205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (SkScalarAbs(unit->fX) < TOLERANCE) { 4305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unit->fX = 0; 4405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unit->fY = SkScalarSign(unit->fY); 4505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else if (SkScalarAbs(unit->fY) < TOLERANCE) { 4605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unit->fX = SkScalarSign(unit->fX); 4705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unit->fY = 0; 4805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 4905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 5005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 5105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid FlingState::reset(float sx, float sy) { 5205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fActive = true; 5305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fDirection.set(sx, sy); 5405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fSpeed0 = SkPoint::Normalize(&fDirection); 5505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fSpeed0 = pin_max_fling(fSpeed0); 5605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fTime0 = getseconds(); 5705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 5805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unit_axis_align(&fDirection); 5905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// printf("---- speed %g dir %g %g\n", fSpeed0, fDirection.fX, fDirection.fY); 6005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 6105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 6205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool FlingState::evaluateMatrix(SkMatrix* matrix) { 6305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (!fActive) { 6405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return false; 6505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 6605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 6705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const float t = getseconds() - fTime0; 6805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const float MIN_SPEED = 2; 6905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const float K0 = 5.0; 7005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const float K1 = 0.02; 7105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger const float speed = fSpeed0 * (sk_float_exp(- K0 * t) - K1); 7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (speed <= MIN_SPEED) { 7305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fActive = false; 7405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return false; 7505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger float dist = (fSpeed0 - speed) / K0; 7705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 7805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// printf("---- time %g speed %g dist %g\n", t, speed, dist); 7905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger float tx = fDirection.fX * dist; 8005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger float ty = fDirection.fY * dist; 8105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER) { 8205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger tx = sk_float_round2int(tx); 8305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger ty = sk_float_round2int(ty); 8405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 8505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger matrix->setTranslate(tx, ty); 8605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// printf("---- evaluate (%g %g)\n", tx, ty); 8705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 8805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return true; 8905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 9005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 9105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger//////////////////////////////////////// 9205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 9305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrAnimateFloat::GrAnimateFloat() : fTime0(0) {} 9405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 9505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrAnimateFloat::start(float v0, float v1, float duration) { 9605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fValue0 = v0; 9705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fValue1 = v1; 9805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fDuration = duration; 9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (duration > 0) { 10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fTime0 = SkTime::GetMSecs(); 10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (!fTime0) { 10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fTime0 = 1; // time0 is our sentinel 10305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 10405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } else { 10505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fTime0 = 0; 10605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 10705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 10805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 10905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerfloat GrAnimateFloat::evaluate() { 11005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (!fTime0) { 11105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return fValue1; 11205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 11305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 11405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger double elapsed = (SkTime::GetMSecs() - fTime0) * 0.001; 11505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (elapsed >= fDuration) { 11605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger fTime0 = 0; 11705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return fValue1; 11805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 11905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 12005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger double t = elapsed / fDuration; 12105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger if (true) { 12205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger t = (3 - 2 * t) * t * t; 12305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 12405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return fValue0 + t * (fValue1 - fValue0); 12505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 12605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 12705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 128