Translating a rotated model.

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Translating a rotated model.

ericg
Hello, This problem is a bit difficult to describe and it is not directly related to JOGL (more of a general 3D programming issue) but since I'm using JOGL I'm hoping there is an exposed openGL function or something that will help me.
What I'm trying to do is rotate a model around a fixed point (can-do no problem) and then translate it along a fixed vector - (can't-do big problem...).
So, if 0,0,0 is my rotation point I need the model to rotate around this point wherever it may be located on the screen.  Then, I need it to translate directly North or South or East or West regardless of the orientation of the model.  Currently, if I rotate the model around the FIXED point 45deg 'left' when I translate in the z direction the model will move North-East.  I need it to maintain its orientation but move directly North.

I have my own rotation and translation functions that have been doing a great job for me so far but it looks like I might need some other construct to accomplish my goal here.  Any help or suggestions would be greatly appreciated.
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

gouessej
Administrator
Hi

You just have to use glPushMatrix, glRotate, glTranslate and glPopMatrix in the right order to make it work, don't you?

Don't reinvent the wheel except for learning purposes, there are already tons of high level APIs based on JogAmp.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

ericg
This post was updated on .
EDIT: Ok, I figured out what I have to do - as always while driving .. :).  After the rotate I have to translate factoring in the rotation angle.
So I will rotate, translate along vector defined by rotation x = cx + (r * cos(a)) , y = cy + (r * sin(a)) r=radius, a=angle, cxy=origin
and then translate by whatever units I am incrementing by.

The above equations are just for finding a point on an arc.  They assume one of the planes is flat (ie in this case the z plane is equivalent across all vectors).




Yes I should have mentioned that I am using shaders and I am trying to avoid deprecated functions.  What seems trivially simple is actually pretty difficult when I have to do the math myself.  My rotate and translate functions do work but when I rotate on a fixed vertex the translate runs along a new vector (eg. if I rotate 90degrees the translate - relative to the screen - on z will run to the east west instead of north south).  I need to keep the translate running north south regardless of the current rotation.
Is there an API out there that would accomplish this?  That's probably what I need.

My current code:

    for (float x = -30;x < 30; x+=2){
    for (float z = -30; z < 30; z+=2){

    {
   
    //rotate on origin
            view2 = rotate(view2,(float)rotAngle,0,1,0);

                        //rotate a model on its own centre. (don't want this)
            /*view2 = translate(view, transX, transY, transZ);
            view2 = rotate(view2,(float)rotAngle,0,1,0);
            view2 = translate(view2, -transX, -transY, -transZ);*/
    }
   
    view2 = translate(view2, (float)transX - x, transY, transZ - z);

                gl.glUniformMatrix4fv(iModelView, 1, false, view2, 0);
                gl.glUniformMatrix4fv(iProjection, 1, false, projection, 0);

                gl.glDrawArrays(GL3.GL_TRIANGLES, 0, 36); //draw 12 triangles (36 vertices).

    }
    }
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

gouessej
Administrator
You can use com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil and com.jogamp.opengl.util.PMVMatrix in order to use the emulation of the fixed pipeline for the programmable pipeline. What you do in your shader is already done in JMonkeyEngine 3 but it's a lot more flexible.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

ericg
Oh, ok I did see PMVMatrix but I was unsure of what it actually did as I couldn't find any documentation for it.  So, I can use it to set Perspective, lookat, rotations etc and then feed the resulting matrix to the shader?  
I did consider JMonkeyEngine but I wanted to keep my imports as simple as possible.  I am a little 'black box shy' you can say.
Thank you very much for your input!


Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

gouessej
Administrator
There are a few unit tests that use PMVMatrix, including this one:
https://github.com/sgothel/jogl/blob/master/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
I tried to use it once but I forgot something and it didn't work. It's probably my fault. Sven knows better than me how to use this feature.

JogAmp's Ardor3D Continuation, JMonkeyEngine, LibGDX and Java 3D aren't black boxes, they are open source. If JOGL is enough for your need and if you want to learn OpenGL, just stick with it but if you don't want to spend a lot of time in writing some boilerplate code (=end up by writing more or less your own scenegraph which is time consuming), I advise you to use a scenegraph. I wrote a detailed tutorial about Java 3D and I'm going to do the same with JogAmp's Ardor3D Continuation. It will contain about 45 simple examples, it will be worth a look.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

Sven Gothel
Administrator
On 09/30/2014 11:02 PM, gouessej [via jogamp] wrote:
> There are a few unit tests that use PMVMatrix, including this one:
> https://github.com/sgothel/jogl/blob/master/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
> I tried to use it once but I forgot something and it didn't work. It's
> probably my fault. Sven knows better than me how to use this feature.

PMVMatrix is just a little convenient helper
bringing you some fixed function math back.

You need to push the PMVMatrix data to your shader uniform ofc
and use it accordingly.

See RedSquareES2 and all the other unit tests for example.

~Sven



signature.asc (828 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

ericg
In reply to this post by gouessej
I'll be looking forward to those Java3D examples.  For now I will stick with JOGL just so I can stay as close to OpenGL as possible but I'm sure I will eventually step forward and make use of some of the engines out there.  Thanks again!
 
Reply | Threaded
Open this post in threaded view
|

Re: Translating a rotated model.

ericg
Just to close out this thread I have the solution.  First I have to say that using Quaternions for rotation is a no brainer - the jogamp Quaternion class is perfect as the rotations seemed to be much smoother than using my own rotation calculations.  Also used the FloatUtils for creating a lookAt matrix.
The core of my problem was that I was focusing on transforming only one axis at a time.  I needed to transform both x and z simultaneously.

    //draw a field of planes adjacent to Y
    for ( x = -10  ;x < 10 ; x+=2){
    for ( z = -10  ; z < 10 ; z+=2){

            //init matrices (thanks FloatUtil!!)
        FloatUtil.makeIdentity(view2);
        FloatUtil.makeIdentity(vw2);


            //set eye, centre and Up (these can be modified via keyboard input etc..)
        float[] eye = {0, 10, -30};
        float[] center = {0,0,0};
        float[] up = {0,1,0};
        float[] mat4Tmp = new float[16];

            //create lookAt matrix (FloatUtil, what would I do without you?)
       FloatUtil.makeLookAt(view2, 0, eye, 0, center, 0, up, 0, mat4Tmp);
       
       //rotate the scene using quaternion. rotangle always +tive 0-360.
        q = q.setIdentity();
        q = q.rotateByAngleNormalAxis( (float) Math.toRadians(rotAngle), 0, 1, 0);
        q = q.normalize();

            //load mx to float array
        q.toMatrix(vw2, 0);
           
            //mult rotation and perspective (can be done in shader, here for testing purposes)
             view2 = multiply( view2, vw2);

             //apply the updated translation co-ords to vertices
        view2 = translate(view2, (float)-transX-x, transY, -(transZ-z));

            gl.glUniformMatrix4fv(iModelView, 1, false, view2, 0);

           //link projection matrix to 'mat4 projection' on vertex shader.
           gl.glUniformMatrix4fv(iProjection, 1, false, projection, 0);

          gl.glDrawArrays(GL3.GL_TRIANGLES, 0, 6); //draw 2 triangles (6 vertices).
                   
    }
    }

//The values for transX, transY and transZ make it all come together.
public void keyPressed(KeyEvent arg0) {
       
        //get camera angle on y axis.
        double convA = Math.toRadians( -rotAngle  + 90);

        switch (arg0.getKeyCode()){
        case KeyEvent.VK_D:
                transZ += Math.sin( convA - Math.PI / 2 );
                transX -= Math.cos( convA - Math.PI / 2 );
                break;
        case KeyEvent.VK_A:
                transZ -= Math.sin( convA - Math.PI / 2 );
                transX += Math.cos( convA - Math.PI / 2 );
                break;
        case KeyEvent.VK_W:
                transZ += Math.sin( convA );
                transX -= Math.cos( convA );
                break;
        case KeyEvent.VK_S:
                transZ -= Math.sin( convA );
                transX += Math.cos( convA );
                break;
        case KeyEvent.VK_Z:
                 rotAngle -= (4);
                 if (rotAngle < 0){
                         rotAngle += 360;
                 }

                break;
        case KeyEvent.VK_X:
                rotAngle += (4);

                break;
        default:
                break;
        }
       
        rotAngle %= 360; //mod 360

}

Works like a charm!  Two weeks later...