私の Android OpenGL ES 2.0 アプリケーションでは、スムーズな画面ドラッグ機能を実装しています。問題は、滑らかな動きが思ったほど滑らかではないことです。
開始するコードは次のとおりです。
public class SoftMoveInfo {
private volatile float mAccumulatedDX = 0.0f;
private volatile float mAccumulatedDY = 0.0f;
private final float mSlowDownMult = 0.1f;
// called by main / input thread
public void addDragDelta(float dx, float dy) {
mAccumulatedDX += dx;
mAccumulatedDY += dy;
}
// called by rendering thread
public void integrate() {
// adjust movement
final float moveSubX = mAccumulatedDX*mSlowDownMult;
final float moveSubY = mAccumulatedDY*mSlowDownMult;
mAccumulatedDX -= moveSubX;
mAccumulatedDY -= moveSubY;
mViewX += moveSubX;
mViewY += moveSubY;
}
}
mViewX
mViewY
シーンがレンダリングされるターゲット画面の「オフセット」値になります。このメソッドintegrate()
はレンダリング スレッドによって呼び出され、基本的に 1 つの移動ステップを進めます。このメソッドaddDragDelta()
は、次のような値を提供するレンダリング スレッドによって呼び出されます。
private float mLastTouchX;
private float mLastTouchY;
private mSoftDragInfo = new SoftMoveInfo();
public boolean onTouchEvent(MotionEvent e) {
final int actionMasked = e.getAction() & MotionEvent.ACTION_MASK;
switch (actionMasked) {
...
case MotionEvent.ACTION_MOVE:
float x = e.getX();
float y = e.getY();
mSoftDragInfo.addDragDelta(x-mLastTouchX, y-mLastTouchY);
mLastTouchX = x;
mLastTouchY = y;
break;
...
}
}
今、出力は本当に「ジッター」です。mAccumulatedDX
メソッド中のロギングから作成したExcelグラフは次のintegrate()
とおりです。
ご覧のとおり、グラフ全体に小さなスパイクがあります。私はそれらを避けたいです。既にすべての読み取りおよび書き込みイベントをブロックに入れようとしましたsynchronized()
が、これは役に立たないようです。スパイクは、レンダリング スレッドがデータを読み取るのと同じ頻度で入力スレッドが情報を提供しないことが原因であると思われます。
滑らかな動きを得るために適切なテクニックは何ですか? ローパス フィルターについて考えましたが、より良いアイデアを受け入れます。