简体   繁体   中英

WebGL interaction, translate after rotate

I'm having a little bit trouble with understanding rotation and translation stuff in context of a WebGL example.

What's going on: I have a sample program that lets me rotate a triangle around its center and translate it on a 2D plane. The code below does exactly that (uses the glmatrix libs). The modelViewMatrix is applied to the triangles vertices.

The issue: If the triangle is rotated by 180°, then the translation is wrong. Of course it is still possible to move the triangle around, but the directions are inverted. If I drag the triangle in an upward direction, the object actually moves further to the bottom of the screen.

The question: What is going on here and why is this happening? What do I need to do to correct this behaviour? I want to be able to drag the triangle no matter by how much it has been rotated, the tranlation axes should be consistent.

Thanks in advance for your replies, I'm sure it is an easy question for someone that is familiar with the whole transformation stuff. :)

var modelViewMatrix = mat4.create();

function mouseDown(mouseEvent){
    isMouseDown = true;
    g_drawInterval = setInterval(redraw, 40);
}

var translationFactor = 0.01;
var rotationFactor = 0.01;  

function mouseMove(mouseEvent){
    if (isMouseDown){
         deltaX = mouseEvent.clientX - oldPosX;
         deltaY = mouseEvent.clientY - oldPosY;
    if (mouseEvent.button === 0) // left mouse button
         mat4.translate(modelViewMatrix, modelViewMatrix,
         [deltaX * translationFactor, -deltaY * translationFactor, 0]);
     else
         mat4.rotateZ(modelViewMatrix, modelViewMatrix,
         deltaX * rotationFactor -deltaY * rotationFactor);
     }
     oldPosX = mouseEvent.clientX;
     oldPosY = mouseEvent.clientY;
 }

The reason for this is that your modelViewMatrix is accumulating the compositions of all the transformations.

The rotation functions typically rotate around the local origin (whatever that is, at the time it is applied). When you have some translate, you shift that origin around, so the rotate will behave differently.

I'm not sure about the "glmatrix" lib and about the shader's you use, but if both follow the default GL convention, you also have the effect that the transformations are applied in reverse order, so that

rotate(...);
translate(...)

will first translate and then rotate.

You can avoid this by keeping track of the orientation and the position separately, ie define a position vector and a rotationMatrix matrix, and update those accordingly. For drawing, you can combine them to the modelview matrix like

 modelViewMatrix=viewMatrix * translate(position) *  rotationMatrix

(Assuming the conventions descirbed above again).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM