From 0107ade0393d100ad9ee43d596faf6ef8dd595e1 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Thu, 19 Sep 2013 21:29:38 +0200 Subject: [PATCH] fix MapAnimator.animateTo() - cleanups --- vtm/src/org/oscim/map/MapAnimator.java | 102 ++++++++++--------------- vtm/src/org/oscim/map/Viewport.java | 29 ++++--- 2 files changed, 56 insertions(+), 75 deletions(-) diff --git a/vtm/src/org/oscim/map/MapAnimator.java b/vtm/src/org/oscim/map/MapAnimator.java index 45805feb..f2175a38 100644 --- a/vtm/src/org/oscim/map/MapAnimator.java +++ b/vtm/src/org/oscim/map/MapAnimator.java @@ -19,6 +19,11 @@ public class MapAnimator { mMap = map; } + private final int ANIM_NONE = 0; + private final int ANIM_MOVE = 1 << 1; + private final int ANIM_SCALE = 1 << 2; + private final int ANIM_FLING = 1 << 3; + private final Map mMap; private final Viewport mViewport; @@ -35,19 +40,17 @@ public class MapAnimator { private float mDuration = 500; private long mAnimEnd = -1; - private boolean mAnimMove; - private boolean mAnimFling; - private boolean mAnimScale; + private int mState = ANIM_NONE; public synchronized void animateTo(BoundingBox bbox) { // TODO for large distatance first scale out, then in // calculate the maximum scale at which the bbox is completely visible double dx = Math.abs(MercatorProjection.longitudeToX(bbox.getMaxLongitude()) - - MercatorProjection.longitudeToX(bbox.getMinLongitude())); + - MercatorProjection.longitudeToX(bbox.getMinLongitude())); double dy = Math.abs(MercatorProjection.latitudeToY(bbox.getMinLatitude()) - - MercatorProjection.latitudeToY(bbox.getMaxLatitude())); + - MercatorProjection.latitudeToY(bbox.getMaxLatitude())); double zx = mMap.getWidth() / (dx * Tile.SIZE); double zy = mMap.getHeight() / (dy * Tile.SIZE); @@ -57,12 +60,12 @@ public class MapAnimator { } public synchronized void animateTo(long duration, GeoPoint geoPoint, double scale, - boolean relative) { + boolean relative) { mViewport.getMapPosition(mPos); if (relative) { - if (mAnimEnd > 0 && mAnimScale) + if (mAnimEnd > 0 && (mState & ANIM_SCALE) != 0) scale = mDeltaPos.scale * scale; else scale = mPos.scale * scale; @@ -86,9 +89,7 @@ public class MapAnimator { mDeltaPos.x -= mStartPos.x; mDeltaPos.y -= mStartPos.y; - mAnimMove = true; - mAnimScale = true; - mAnimFling = false; + mState = ANIM_MOVE | ANIM_SCALE; animStart(duration); } @@ -97,7 +98,7 @@ public class MapAnimator { mViewport.getMapPosition(mPos); - if (mAnimEnd > 0 && mAnimScale) + if (mAnimEnd > 0 && (mState & ANIM_SCALE) != 0) scale = mDeltaPos.scale * scale; else scale = mPos.scale * scale; @@ -109,16 +110,13 @@ public class MapAnimator { mScaleBy = mPos.scale * scale - mPos.scale; - mStartPos.scale = mPos.scale; mStartPos.angle = mPos.angle; mPivot.x = pivotX; mPivot.y = pivotY; - mAnimScale = true; - mAnimFling = false; - mAnimMove = false; + mState = ANIM_SCALE; animStart(duration); } @@ -128,7 +126,7 @@ public class MapAnimator { } public synchronized void animateFling(int velocityX, int velocityY, - int minX, int maxX, int minY, int maxY) { + int minX, int maxX, int minY, int maxY) { if (velocityX * velocityX + velocityY * velocityY < 2048) return; @@ -147,54 +145,28 @@ public class MapAnimator { FastMath.clamp(mVelocity.x, minX, maxX); FastMath.clamp(mVelocity.y, minY, maxY); - mAnimFling = true; - mAnimMove = false; - mAnimScale = false; + mState = ANIM_FLING; + animStart(duration); } - private void animStart(float duration) { mDuration = duration; - mAnimEnd = System.currentTimeMillis() + (long) duration; mMap.render(); } private void animCancel() { - mAnimEnd = -1; - mAnimScale = false; - mAnimFling = false; - mAnimMove = false; - + mState = ANIM_NONE; mPivot.x = 0; mPivot.y = 0; } - private boolean fling(float adv) { - synchronized (mViewport) { - - adv = (float) Math.sqrt(adv); - - double dx = mVelocity.x * adv; - double dy = mVelocity.y * adv; - - if (dx == 0 && dy == 0) - return false; - - mViewport.moveMap((float) (dx - mScroll.x), (float) (dy - mScroll.y)); - - mScroll.x = dx; - mScroll.y = dy; - } - return true; - } - /** * called by GLRenderer at begin of each frame. */ public void updateAnimation() { - if (mAnimEnd < 0) + if (mState == ANIM_NONE) return; long millisLeft = mAnimEnd - System.currentTimeMillis(); @@ -210,17 +182,18 @@ public class MapAnimator { if (millisLeft <= 0) { // set final position - if (mAnimMove && !mAnimFling) - mViewport.moveInternal(mStartPos.x + mDeltaPos.x, mStartPos.y + mDeltaPos.y); + if ((mState & ANIM_MOVE) != 0) + mViewport.moveInternal(mStartPos.x + mDeltaPos.x, + mStartPos.y + mDeltaPos.y); - if (mAnimScale) { + if ((mState & ANIM_SCALE) != 0) { if (mScaleBy > 0) doScale(mStartPos.scale + (mScaleBy - 1)); else doScale(mStartPos.scale + mScaleBy); } - mMap.updateMap(true); + mMap.updateMap(true); animCancel(); return; } @@ -229,7 +202,7 @@ public class MapAnimator { float adv = (1.0f - millisLeft / mDuration); - if (mAnimScale) { + if ((mState & ANIM_SCALE) != 0) { if (mScaleBy > 0) doScale(mStartPos.scale + (mScaleBy * (Math.pow(2, adv) - 1))); else @@ -238,11 +211,9 @@ public class MapAnimator { changed = true; } - if (mAnimMove) { - mViewport.moveInternal( - mStartPos.x + mDeltaPos.x * adv, - mStartPos.y + mDeltaPos.y * adv); - + if ((mState & ANIM_MOVE) != 0) { + mViewport.moveInternal(mStartPos.x + mDeltaPos.x * adv, + mStartPos.y + mDeltaPos.y * adv); changed = true; } @@ -251,12 +222,22 @@ public class MapAnimator { // updateMatrix(); //} - if (mAnimFling && fling(adv)) - changed = true; + if ((mState & ANIM_FLING) != 0) { + adv = (float) Math.sqrt(adv); + double dx = mVelocity.x * adv; + double dy = mVelocity.y * adv; + if ((dx - mScroll.x) != 0 || (dy - mScroll.y) != 0) { + mViewport.moveMap((float) (dx - mScroll.x), (float) (dy - mScroll.y)); + mScroll.x = dx; + mScroll.y = dy; + + changed = true; + } + } // continue animation if (changed) { - // inform other layers that position has changed + // render and inform layers that position has changed mMap.updateMap(true); } else { // just render next frame @@ -269,6 +250,7 @@ public class MapAnimator { } private void doScale(double newScale) { - mViewport.scaleMap((float) (newScale / mPos.scale), (float)mPivot.x, (float)mPivot.y); + mViewport.scaleMap((float) (newScale / mPos.scale), + (float) mPivot.x, (float) mPivot.y); } } diff --git a/vtm/src/org/oscim/map/Viewport.java b/vtm/src/org/oscim/map/Viewport.java index dc170a8a..8b1cf9be 100644 --- a/vtm/src/org/oscim/map/Viewport.java +++ b/vtm/src/org/oscim/map/Viewport.java @@ -82,7 +82,7 @@ public class Viewport { float[] tmp = new float[16]; Matrix4.frustumM(tmp, 0, -s, s, - aspect * s, -aspect * s, VIEW_NEAR, VIEW_FAR); + aspect * s, -aspect * s, VIEW_NEAR, VIEW_FAR); mProjMatrix.set(tmp); mTmpMatrix.setTranslation(0, 0, -VIEW_DISTANCE); @@ -107,10 +107,10 @@ public class Viewport { public synchronized boolean getMapPosition(MapPosition pos) { boolean changed = (pos.scale != mPos.scale - || pos.x != mPos.x - || pos.y != mPos.y - || pos.angle != mPos.angle - || pos.tilt != mPos.tilt); + || pos.x != mPos.x + || pos.y != mPos.y + || pos.angle != mPos.angle + || pos.tilt != mPos.tilt); pos.angle = mPos.angle; pos.tilt = mPos.tilt; @@ -295,8 +295,8 @@ public class Viewport { public synchronized GeoPoint fromScreenPoint(float x, float y) { fromScreenPoint(x, y, mMovePoint); return new GeoPoint( - MercatorProjection.toLatitude(mMovePoint.y), - MercatorProjection.toLongitude(mMovePoint.x)); + MercatorProjection.toLatitude(mMovePoint.y), + MercatorProjection.toLongitude(mMovePoint.x)); } /** @@ -423,19 +423,18 @@ public class Viewport { Point p = applyRotation(mx, my); double tileScale = mPos.scale * Tile.SIZE; - moveBy(p.x / tileScale, p.y / tileScale); + moveTo(mPos.x - p.x / tileScale, mPos.y - p.y / tileScale); } /* used by MapAnimator */ void moveInternal(double mx, double my) { Point p = applyRotation(mx, my); - moveBy(p.x, p.y); + moveTo(p.x, p.y); } - /* used by MapAnimator */ - void moveBy(double mx, double my) { - mPos.x -= mx; - mPos.y -= my; + private void moveTo(double x, double y) { + mPos.x = x; + mPos.y = y; // clamp latitude mPos.y = FastMath.clamp(mPos.y, 0, 1); @@ -447,7 +446,7 @@ public class Viewport { mPos.x += 1; } - Point applyRotation(double mx, double my) { + private Point applyRotation(double mx, double my) { if (mPos.angle == 0) { mMovePoint.x = mx; mMovePoint.y = my; @@ -489,7 +488,7 @@ public class Viewport { if (pivotX != 0 || pivotY != 0) moveMap(pivotX * (1.0f - scale), - pivotY * (1.0f - scale)); + pivotY * (1.0f - scale)); return true; }