michael@0: /* michael@0: * Copyright (C) 2012 The Android Open Source Project michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: #define LOG_TAG "VelocityControl" michael@0: //#define LOG_NDEBUG 0 michael@0: michael@0: // Log debug messages about acceleration. michael@0: #define DEBUG_ACCELERATION 0 michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "VelocityControl.h" michael@0: #include michael@0: #include michael@0: michael@0: namespace android { michael@0: michael@0: // --- VelocityControl --- michael@0: michael@0: const nsecs_t VelocityControl::STOP_TIME; michael@0: michael@0: VelocityControl::VelocityControl() { michael@0: reset(); michael@0: } michael@0: michael@0: void VelocityControl::setParameters(const VelocityControlParameters& parameters) { michael@0: mParameters = parameters; michael@0: reset(); michael@0: } michael@0: michael@0: void VelocityControl::reset() { michael@0: mLastMovementTime = LLONG_MIN; michael@0: mRawPosition.x = 0; michael@0: mRawPosition.y = 0; michael@0: mVelocityTracker.clear(); michael@0: } michael@0: michael@0: void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { michael@0: if ((deltaX && *deltaX) || (deltaY && *deltaY)) { michael@0: if (eventTime >= mLastMovementTime + STOP_TIME) { michael@0: #if DEBUG_ACCELERATION michael@0: ALOGD("VelocityControl: stopped, last movement was %0.3fms ago", michael@0: (eventTime - mLastMovementTime) * 0.000001f); michael@0: #endif michael@0: reset(); michael@0: } michael@0: michael@0: mLastMovementTime = eventTime; michael@0: if (deltaX) { michael@0: mRawPosition.x += *deltaX; michael@0: } michael@0: if (deltaY) { michael@0: mRawPosition.y += *deltaY; michael@0: } michael@0: mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition); michael@0: michael@0: float vx, vy; michael@0: float scale = mParameters.scale; michael@0: if (mVelocityTracker.getVelocity(0, &vx, &vy)) { michael@0: float speed = hypotf(vx, vy) * scale; michael@0: if (speed >= mParameters.highThreshold) { michael@0: // Apply full acceleration above the high speed threshold. michael@0: scale *= mParameters.acceleration; michael@0: } else if (speed > mParameters.lowThreshold) { michael@0: // Linearly interpolate the acceleration to apply between the low and high michael@0: // speed thresholds. michael@0: scale *= 1 + (speed - mParameters.lowThreshold) michael@0: / (mParameters.highThreshold - mParameters.lowThreshold) michael@0: * (mParameters.acceleration - 1); michael@0: } michael@0: michael@0: #if DEBUG_ACCELERATION michael@0: ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): " michael@0: "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f", michael@0: mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, michael@0: mParameters.acceleration, michael@0: vx, vy, speed, scale / mParameters.scale); michael@0: #endif michael@0: } else { michael@0: #if DEBUG_ACCELERATION michael@0: ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity", michael@0: mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, michael@0: mParameters.acceleration); michael@0: #endif michael@0: } michael@0: michael@0: if (deltaX) { michael@0: *deltaX *= scale; michael@0: } michael@0: if (deltaY) { michael@0: *deltaY *= scale; michael@0: } michael@0: } michael@0: } michael@0: michael@0: } // namespace android