Good day my fellow developers,
I'm a new here and this is my first post on GD. My background is 10 years of programming in different platforms and languages including C#, Java, Linux Kernel Dev, Java Card, ... Android is something new to me (4 months so far). Some month ago I started to use OpenGl ES.
So what I'm trying to write is OpenGl ES app which shows map. The map is rotated using magnetometer (map rotates in opposite direction of the device's rotation). For zooming I'm using ScaleGestureDetector and passing scale factor to Matrix.scaleM. My current problem is panning.
GlSurfaceView side:
private void handlePanAndZoom(MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
// Get the index of the pointer associated with the action.
int index = MotionEventCompat.getActionIndex(event);
int xPos = (int) MotionEventCompat.getX(event, index);
int yPos = (int) MotionEventCompat.getY(event, index);
mScaleDetector.onTouchEvent(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
mRenderer.handleStartPan(xPos, yPos);
break;
case MotionEvent.ACTION_MOVE:
if (!mScaleDetector.isInProgress()) {
mRenderer.handlePan(xPos, yPos);
}
break;
}
}
Renderer side:
private static final PointF mPanStart = new PointF();
public void handleStartPan(final int x, final int y) {
runOnGlThread(new Runnable() {
@Override
public void run() {
windowToWorld(x, y, mPanStart);
}
});
}
private static final PointF mCurrentPan = new PointF();
public void handlePan(final int x, final int y) {
runOnGlThread(new Runnable() {
@Override
public void run() {
windowToWorld(x, y, mCurrentPan);
float dx = mCurrentPan.x - mPanStart.x;
float dy = mCurrentPan.y - mPanStart.y;
mOffsetX += dx;
mOffsetY += dy;
updateModelMatrix();
mPanStart.set(mCurrentPan);
}
});
}
windowToWorld function uses gluUnProject and I know it works because I'm using it for other tasks. updateModelMatrix() func:
private void updateModelMatrix() {
Matrix.setIdentityM(mScaleMatrix,0);
Matrix.scaleM(mScaleMatrix, 0, mScale, mScale, mScale);
Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f);
Matrix.setIdentityM(mTranslationMatrix,0);
Matrix.translateM(mTranslationMatrix, 0, mOffsetX, mOffsetY, 0);
// Model = Scale * Rotate * Translate
Matrix.multiplyMM(mIntermediateMatrix, 0, mScaleMatrix, 0, mRotationMatrix, 0);
Matrix.multiplyMM(mModelMatrix, 0, mIntermediateMatrix, 0, mTranslationMatrix, 0);
}
Same mModelMatrix is used in gluUnproject of windowToWorld function for point translation.
So my problem two-fold:
- The panning occurs twice slower than the movement of finger on the device's screen
- At some point when panning continuously for a few seconds (making circles on screen, for example) the map starts to 'shake'. The amplitude of this shaking is getting bigger and bigger. Looks like some value adds up in handlePan iterations and causes this effect.
Any idea why these happen?
Thank you in advance, Greg.
P.S> I didn't want to overwhelm the post with code, so I tried to put only relevant functions. Please let me know if there is anything missing to understand the question.