update map position animation at beginning of each frame
This commit is contained in:
parent
6cfc776911
commit
0a2bb1026e
@ -253,13 +253,13 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
// get current MapPosition, set mBoxCoords (mapping of screen to model
|
||||
// coordinates)
|
||||
MapPosition pos = mMapPosition;
|
||||
|
||||
synchronized (mMapViewPosition) {
|
||||
// update MapPosition
|
||||
mMapViewPosition.updateAnimation();
|
||||
|
||||
// get current MapPosition
|
||||
changed = mMapViewPosition.getMapPosition(pos);
|
||||
|
||||
if (changed)
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.oscim.view;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import org.oscim.core.BoundingBox;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
@ -28,11 +26,7 @@ import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.Matrix4;
|
||||
|
||||
import android.opengl.Matrix;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
|
||||
public class MapViewPosition {
|
||||
private static final String TAG = MapViewPosition.class.getName();
|
||||
@ -90,8 +84,6 @@ public class MapViewPosition {
|
||||
// scale map plane at VIEW_DISTANCE to near plane
|
||||
public final static float VIEW_SCALE = (VIEW_NEAR / VIEW_DISTANCE) * 0.5f;
|
||||
|
||||
private final AnimationHandler mHandler;
|
||||
|
||||
MapViewPosition(MapView mapView) {
|
||||
mMapView = mapView;
|
||||
|
||||
@ -103,8 +95,6 @@ public class MapViewPosition {
|
||||
mTilt = 0;
|
||||
|
||||
updatePosition();
|
||||
|
||||
mHandler = new AnimationHandler(this);
|
||||
}
|
||||
|
||||
private void updatePosition() {
|
||||
@ -433,10 +423,9 @@ public class MapViewPosition {
|
||||
*/
|
||||
public synchronized void moveMap(float mx, float my) {
|
||||
// stop animation
|
||||
mHandler.cancel();
|
||||
animCancel();
|
||||
|
||||
PointD p = applyRotation(mx, my);
|
||||
|
||||
move(p.x, p.y);
|
||||
}
|
||||
|
||||
@ -499,7 +488,7 @@ public class MapViewPosition {
|
||||
*/
|
||||
public synchronized boolean scaleMap(float scale, float pivotX, float pivotY) {
|
||||
// stop animation
|
||||
mHandler.cancel();
|
||||
animCancel();
|
||||
|
||||
// just sanitize input
|
||||
scale = FastMath.clamp(scale, 0.5f, 2);
|
||||
@ -595,7 +584,7 @@ public class MapViewPosition {
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
// TODO move to MapAnimator:
|
||||
// TODO move to MapAnimator
|
||||
|
||||
private double mScrollX;
|
||||
private double mScrollY;
|
||||
@ -611,10 +600,11 @@ public class MapViewPosition {
|
||||
private float mDuration = 500;
|
||||
private final static double LOG4 = Math.log(4);
|
||||
|
||||
private long mAnimEnd = -1;
|
||||
|
||||
private boolean mAnimMove;
|
||||
private boolean mAnimFling;
|
||||
private boolean mAnimScale;
|
||||
private final AccelerateDecelerateInterpolator mDecInterpolator = new AccelerateDecelerateInterpolator();
|
||||
|
||||
public synchronized void animateTo(BoundingBox bbox) {
|
||||
|
||||
@ -656,9 +646,7 @@ public class MapViewPosition {
|
||||
mAnimMove = true;
|
||||
mAnimScale = true;
|
||||
mAnimFling = false;
|
||||
mDuration = 500;
|
||||
|
||||
mHandler.start((int) mDuration);
|
||||
animStart(500);
|
||||
}
|
||||
|
||||
public synchronized void animateTo(GeoPoint geoPoint) {
|
||||
@ -676,23 +664,31 @@ public class MapViewPosition {
|
||||
mAnimMove = true;
|
||||
mAnimScale = false;
|
||||
mAnimFling = false;
|
||||
animStart(300);
|
||||
}
|
||||
|
||||
mDuration = 300;
|
||||
mHandler.start(mDuration);
|
||||
private void animStart(float duration) {
|
||||
mDuration = duration;
|
||||
|
||||
mAnimEnd = System.currentTimeMillis() + (long) duration;
|
||||
mMapView.render();
|
||||
}
|
||||
|
||||
private void animCancel() {
|
||||
mAnimEnd = -1;
|
||||
}
|
||||
|
||||
synchronized boolean fling(float adv) {
|
||||
|
||||
//float delta = (mDuration - millisLeft) / mDuration;
|
||||
adv = (float) Math.sqrt(adv);
|
||||
//adv = Interpolation.pow2Out.apply(adv);
|
||||
|
||||
float dx = mVelocityX * adv;
|
||||
float dy = mVelocityY * adv;
|
||||
|
||||
if (dx != 0 || dy != 0) {
|
||||
moveMap((float) (dx - mScrollX), (float) (dy - mScrollY));
|
||||
PointD p = applyRotation((float) (dx - mScrollX), (float) (dy - mScrollY));
|
||||
move(p.x, p.y);
|
||||
|
||||
mMapView.redrawMap(true);
|
||||
mScrollX = dx;
|
||||
mScrollY = dy;
|
||||
}
|
||||
@ -705,55 +701,66 @@ public class MapViewPosition {
|
||||
public synchronized void animateFling(int velocityX, int velocityY,
|
||||
int minX, int maxX, int minY, int maxY) {
|
||||
|
||||
if (velocityX * velocityX + velocityY * velocityY < 3600)
|
||||
if (velocityX * velocityX + velocityY * velocityY < 4096)
|
||||
return;
|
||||
|
||||
mScrollX = 0;
|
||||
mScrollY = 0;
|
||||
|
||||
mDuration = 500;
|
||||
float duration = 500;
|
||||
|
||||
mVelocityX = velocityX * (mDuration / 1000);
|
||||
mVelocityY = velocityY * (mDuration / 1000);
|
||||
// pi times thumb..
|
||||
float flingFactor = (duration / 2500);
|
||||
mVelocityX = velocityX * flingFactor;
|
||||
mVelocityY = velocityY * flingFactor;
|
||||
FastMath.clamp(mVelocityX, minX, maxX);
|
||||
FastMath.clamp(mVelocityY, minY, maxY);
|
||||
|
||||
// mScroller.fling(0, 0, velocityX, velocityY, minX, maxX, minY, maxY);
|
||||
mAnimFling = true;
|
||||
mAnimMove = false;
|
||||
mAnimScale = false;
|
||||
|
||||
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
|
||||
|
||||
mHandler.start(mDuration);
|
||||
animStart(duration);
|
||||
}
|
||||
|
||||
public synchronized void animateZoom(float scale) {
|
||||
mStartScale = mAbsScale;
|
||||
mEndScale = mAbsScale * scale - mAbsScale;
|
||||
|
||||
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
|
||||
|
||||
mDuration = 300;
|
||||
mHandler.start(mDuration);
|
||||
animStart(300);
|
||||
}
|
||||
|
||||
/**
|
||||
* called by GLRenderer at begin of each frame.
|
||||
*/
|
||||
public void updateAnimation() {
|
||||
//scroll();
|
||||
}
|
||||
if (mAnimEnd < 0)
|
||||
return;
|
||||
|
||||
long millisLeft = mAnimEnd - System.currentTimeMillis();
|
||||
|
||||
if (millisLeft <= 0) {
|
||||
// set final position
|
||||
if (mAnimMove) {
|
||||
moveAbs(mStartX + mEndX, mStartY + mEndY);
|
||||
}
|
||||
|
||||
if (mAnimScale) {
|
||||
mAbsScale = mStartScale + mEndScale;
|
||||
}
|
||||
|
||||
updatePosition();
|
||||
mMapView.redrawMap(true);
|
||||
|
||||
mAnimEnd = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void onTick(long millisLeft) {
|
||||
boolean changed = false;
|
||||
|
||||
float adv = (1.0f - millisLeft / mDuration);
|
||||
adv = mDecInterpolator.getInterpolation(adv);
|
||||
|
||||
if (mAnimScale) {
|
||||
if (mEndScale > 0)
|
||||
// double s = (1 + adv * adv * mEndScale);
|
||||
// mAbsScale = mStartScale * s;
|
||||
// Log.d(TAG, "scale: " + s + " " + mAbsScale + " " + mStartScale);
|
||||
//}
|
||||
mAbsScale = mStartScale + (mEndScale * (Math.pow(2, adv) - 1));
|
||||
else
|
||||
mAbsScale = mStartScale + (mEndScale * adv);
|
||||
@ -778,96 +785,13 @@ public class MapViewPosition {
|
||||
if (mAnimFling && fling(adv))
|
||||
changed = true;
|
||||
|
||||
if (changed)
|
||||
// continue animation
|
||||
if (changed) {
|
||||
// inform other layers that position has changed
|
||||
mMapView.redrawMap(true);
|
||||
}
|
||||
|
||||
void onFinish() {
|
||||
|
||||
if (mAnimMove) {
|
||||
moveAbs(mStartX + mEndX, mStartY + mEndY);
|
||||
}
|
||||
|
||||
if (mAnimScale) {
|
||||
mAbsScale = mStartScale + mEndScale;
|
||||
}
|
||||
|
||||
updatePosition();
|
||||
|
||||
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
|
||||
mMapView.redrawMap(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* below is borrowed from CountDownTimer class:
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*/
|
||||
static class AnimationHandler extends Handler {
|
||||
private final WeakReference<MapViewPosition> mMapViewPosition;
|
||||
private static final int MSG = 1;
|
||||
|
||||
long mMillisInFuture;
|
||||
|
||||
long mInterval = 16;
|
||||
|
||||
long mStopTimeInFuture;
|
||||
|
||||
AnimationHandler(MapViewPosition mapAnimator) {
|
||||
mMapViewPosition = new WeakReference<MapViewPosition>(mapAnimator);
|
||||
}
|
||||
|
||||
public synchronized final void start(float millis) {
|
||||
mMillisInFuture = (int) millis;
|
||||
MapViewPosition animator = mMapViewPosition.get();
|
||||
if (animator == null)
|
||||
return;
|
||||
|
||||
if (mMillisInFuture <= 0) {
|
||||
animator.onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
|
||||
removeMessages(MSG);
|
||||
sendMessage(obtainMessage(MSG));
|
||||
}
|
||||
|
||||
public final void cancel() {
|
||||
removeMessages(MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
MapViewPosition animator = mMapViewPosition.get();
|
||||
if (animator == null)
|
||||
return;
|
||||
|
||||
final long millisLeft = mStopTimeInFuture
|
||||
- SystemClock.elapsedRealtime();
|
||||
|
||||
if (millisLeft <= 0) {
|
||||
animator.onFinish();
|
||||
} else if (millisLeft < mInterval) {
|
||||
// no tick, just delay until done
|
||||
sendMessageDelayed(obtainMessage(MSG), millisLeft);
|
||||
} else {
|
||||
long lastTickStart = SystemClock.elapsedRealtime();
|
||||
animator.onTick(millisLeft);
|
||||
|
||||
// take into account user's onTick taking time to
|
||||
// execute
|
||||
long delay = lastTickStart + mInterval
|
||||
- SystemClock.elapsedRealtime();
|
||||
|
||||
// special case: user's onTick took more than interval
|
||||
// to
|
||||
// complete, skip to next interval
|
||||
while (delay < 0)
|
||||
delay += mInterval;
|
||||
|
||||
sendMessageDelayed(obtainMessage(MSG), delay);
|
||||
}
|
||||
} else {
|
||||
// just render next frame
|
||||
mMapView.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user