tags:

views:

68

answers:

1
A: 

Yeah, I ran into this problem too.

What you need to do is keep a rotation matrix around that "accumulates" the current state of rotation, and use it in addition to the rotation matrix that comes from the current dragging operation.

Say you have two matrices, lastRotMx and currRotMx. Make them members of CubeDrawingArea if you like.

You haven't shown us this, but I assume that m_lastTrackPoint is initialized whenever the mouse button goes down for dragging. When that happens, copy currRotMx into lastRotMx.

Then in on_motion_notify_event(), after you calculate m_rotAxis and m_angle, create a new rotation matrix draggingRotMx based on m_rotAxis and m_angle; then multiply lastRotMx by draggingRotMx and put the result in currRotMx.

Finally, in redraw(), instead of

   glRotated(m_angle, m_rotAxis.x, m_rotAxis.y, m_rotAxis.z);

rotate by currRotMx.

Update: Or instead of all that... I haven't tested this, but I think it would work:

Make cur_pos a class member so it stays around, but it's initialized to zero, as is m_lastTrackPoint. Then, whenever a new drag motion is started, before you initialize m_lastTrackPoint, let _3V dpos = cur_pos - m_lastTrackPoint (pseudocode). Finally, when you do initialize m_lastTrackPoint based on the mouse event coords, subtract dpos from it.

That way, your cur_pos will already be offset from m_lastTrackPoint by an amount based on the accumulation of offsets from past arcball drags.

Probably error would accumulate as well, but it should be gradual enough so as not to be noticeable. But I'd want to test it to be sure... composed rotations are tricky enough that I don't trust them without seeing them.

P.S. your username is demotivating. Suggest picking another one.

P.P.S. For those who come later searching for answers to this question, the keywords to search on are "arcball rotation". An definitive article is Ken Shoemake's section in Graphical Gems IV. See also this arcball tutorial for JOGL.

LarsH
I really don't see how your first suggestion could work. The rotation angle is still a function of the current drag offset, so in that case I'll just be using a different method to rotate the cube, but afterwards, I'll go to rotate again, the angle will be close to zero, and I'm back to square one. In fact, on a lark, I did implement your suggestion and got the same results.
Bitch-Face Jones
As for your second suggestion, I tried a bit of a variation on it where I maintain the current trackball position as a member, setting m_lastTrackPoint = current track point before redraw, and removing the calls to glPushMatrix() and glPopMatrix() in the redraw function. This keeps it from being "reset" the next time I go to rotate, but now on the next rotate, it's rotating in the transformed coordinate system (I'm assuming) so I get weird results...
Bitch-Face Jones
@Bit: re: 1st comment: the rotation angle (in redraw()) is not just a function of the current drag offset, but of the accumulated rotation *and* the current drag offset. Are you saving currRotMx into lastRotMx when you start dragging, and setting currRotMx to be the product of draggingRotMx and lastRotMx whenever you drag?
LarsH
@Bit: re: 2nd comment: yeah, I think I tried your variation as well and it didn't work. As you say, it's rotating in the transformed coordinate system, so it won't work. As you know, rotations have to be composed in the right order.
LarsH
@Bit: my sample code is at http://www.huttar.net/lars-kathy/tmp/netwalk3D/netwalk3D.html; see the js file it loads. The arcball rotation worked (cumulatively) with an earlier version of WebGL; may not work now. But the code should still convey the method more precisely.
LarsH
Okay, I must have screwed something up when I implemented your first suggestion the first time around, because I tried it again and now it more or less works. I'm still having some issues with it getting wonky after a while, but I at least have a place to start now. Thanks.
Bitch-Face Jones
@Bit: glad it's at least basically working now. See the new PPS on my answer for some further references on arcball rotation. They may address the issue of degrading accuracy.
LarsH