1
\$\begingroup\$

I've finally got interpolation working to 'smooth' out movement, however it doesn't seem to work for objects that are rotating (around their own center) - when I try to do this, the objects in question 'wobble'.

Note: I'm not talking about interpolating the actual rotation but rather the movement of a rotated object

So, let's say I have an object moving from left to right. Using the code below (with interpolation), it moves nice and smoothly. However, after rotating the object (let's say by 45 degrees, but this could be any angle), it's no longer moving smoothly, it still moves along it's path (left to right in this case) but it's no longer smooth.

Main Game Loop

@Override
public void onDrawFrame(GL10 gl) {

    //Grab time
    newTime = System.currentTimeMillis()*0.001;
    frameTime = newTime - currentTime;
    if ( frameTime > (dt*25))
        frameTime = (dt*25);

    currentTime = newTime;

    accumulator += frameTime;

    //Save game-state and update logic
    while (accumulator >= dt){
        saveGameState();  //Back up positions before updating them
        updateLogic(); //Update logic
        t += dt;
        accumulator -= dt;
    }

    //Get the amount to interpolate by
    interpolation = (float) (accumulator / dt);

    //Interpolate positions and render
    interpolate();      
    render(interpolation);
}

Rotation Code

public void rotate(float x, float y, float angle){

    //Rotate the quad   
    Matrix.setIdentityM(mRotationMatrix, 0);
    Matrix.translateM(mRotationMatrix, 0, centreX, centreY, 0f);
    Matrix.rotateM(mRotationMatrix, 0, angle, 0, 0, 0.1f);
    Matrix.translateM(mRotationMatrix, 0, -centreX, -centreY, 0f);
}

Edit

OK so it appears this is the problem:

  • During logic update, sprite is moved and rotates it around it's center (using it's new/current X and Y to calculate it's center).
  • Get's to render()
  • Render method interpolates position creating new 'throwaway' coordinates at which object should be drawn
  • Render method draws sprite at it's 'render' x and y coordinates
  • Logic update moves and rotate around it actual x and y - not it's 'rendering x and y
  • and so on

So as you can see, it's being rotated, not around the coordinates that it's been drawn at but at it's actual coordinates. I can't rotate it around it's render coordinates, because the rotation is done within the logic update, not during the render call, therefore, it would be rotating it around it 'old' render position, not the next one and I won't know the new render coordinates until the next render call which means.........

That the only way I can do this, is to actually translate / rotate the sprite within the render routine and not the logic routine.

I've tried this and it works, but not sure I'm happy about piling more 'logic' into my render routine.

Is this an 'acceptable' model? How else can I achieve rotation while keeping the object nicely interpolated?!

\$\endgroup\$
  • \$\begingroup\$ working through your code in my head, im curious why in rotate you are translating around a negative origin? Matrix.translateM(mRotationMatrix, 0, -centreX, -centreY, 0f); \$\endgroup\$ – Joe Sep 8 '14 at 18:33
  • \$\begingroup\$ Hi @Joe, yeah, you're right. I will post another question regarding that :-) that's been a long standing problem, I must have something wrong in my shader because if I specify 45 as rotation amount, it rotates in the opposite direction, so I simply negated this to make my code more readable. I'll correct this for this question to take away any confusion, but I will definitely post another question regarding this because I've never been able to work out why this is..... cheers! \$\endgroup\$ – BungleBonce Sep 8 '14 at 18:39
  • \$\begingroup\$ id venture a guess your issues are happening here by first translating, rotating then translating back along x & y \$\endgroup\$ – Joe Sep 8 '14 at 18:40
  • \$\begingroup\$ I should point out @Jo that if I remove the interpolation completely, then the rotation doesn't cause any 'wobbling' (although then of course, I would get choppiness which the interpolation sorts out), the rotation is only causing an issue when used in conjunction with interpolation. Hope this makes sense. Would appreciate if you could elaborate. Thanks \$\endgroup\$ – BungleBonce Sep 8 '14 at 18:52
1
\$\begingroup\$

from looking at the docs I have found your issue

public static void rotateM (float[] m, int mOffset, float a, float x, float y, float z) Added in API level 1

Rotates matrix m in place by angle a (in degrees) around the axis (x, y, z).

Parameters:

  • m source matrix
  • mOffset index into m where the matrix starts a angle to rotate in degrees
  • x X axis component
  • y Y axis component
  • z Z axis component

Matrix.rotateM(mRotationMatrix, 0, angle, 0, 0, 0.1f);

looks like this function is meant to rotate around an axis and your passing the axis of ( 0,0,0.1f ) when you probably mean to be rotating this object around its local origin

local origin rotation: (this is what you want to be doing)

rotation around local origin

rotation around world point: (this is what you are currently doing)

this would very probably change position, thus ruining your interpolation

rotation around world point

you can change your rotateM call to look like this

Matrix.rotateM(mRotationMatrix, 0, angle, ORIGIN_X, ORIGIN_Y, ORIGIN_Z);

\$\endgroup\$
  • \$\begingroup\$ Joe is on the right track, I think. Most matrix rotation functions that work in 3D expect the axis to be passed in a normalized form. Try normalizing your axis before passing it in i.e. Matrix.rotateM(mRotationMatrix, 0, angle, 0, 0, 1.0f); \$\endgroup\$ – user47946 Sep 8 '14 at 19:20
  • \$\begingroup\$ Thanks @Joe, I attempted to use 1.0f instead of 0.1f (as user47946 suggested), but this didn't make any difference. Is this what you meant? Thanks for your help. \$\endgroup\$ – BungleBonce Sep 8 '14 at 20:34
  • \$\begingroup\$ no take a second look ive added an edit... you are attempting to rotate an object around the 3d point (0,0,0.1) which is causing position distortion... you want to rotate it around its own center point aka local origin (originX, originY, originZ) \$\endgroup\$ – Joe Sep 8 '14 at 20:36
  • \$\begingroup\$ OK @Joe thanks, I'll have to have a go at this, I don't quite understand as I tought that Matrix.translateM(mRotationMatrix, 0, centreX, centreY, 0f), centered the object in the center if the GL Viewport then you rotated it around the center, then translated it back into position (hence the use of negative values for the 2nd translateM line). I may have misunderstood. Also, rotation (as I'm doing it) works fine if I don't interpolate (or if the object isn't moving) - it does rotate around it's own center, I'll re-read the docs and see if I've got this all wrong! Cheers \$\endgroup\$ – BungleBonce Sep 8 '14 at 21:26
  • \$\begingroup\$ not a problem imagine the difference between the earth revolving around the sun and the earth rotating around its axis... very loose analogy but i hope it helps \$\endgroup\$ – Joe Sep 8 '14 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.