Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: rotation & display

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2001
    Location
    Concord, CA, USA
    Posts
    19

    rotation & display

    I have a world coordinate model, which I read from a file (the positon can be anywhere) with me.
    I am trying to do 2 things:

    1. To display the entire model.

    2. To rotate the model on it's own centric axis (ie, rotate about the axis which passes thru the center of the model in any 3 directions).

    1. I have done first one by calling glOrtho()
    and glTranslatef() (this is tricky as i have to generalize any data).

    2. After displaying the model in window, when I try to rotate the model around it's own axis, it rotates as if the origin is in the world coord.

    one condition: The model rotates around it's own axis after translating the model to the origin. But I don't want to do that as it is expensive to transform all points of the data.

    Thanks in advance,
    R.B
    R.B

  2. #2
    Member Regular Contributor
    Join Date
    Feb 2001
    Location
    Australia
    Posts
    431

    Re: rotation & display

    If the model is defined with respect to its own central axis, you should be able to just do this:
    Code :
    const float z_offset(-a_large_enough_float);
    ...
    // Move the "camera" down the z axis.
    glTranslatef(0.0f, 0.0f, z_offset);
    // Rotate the model around an axis.
    glRotatef(rotate_angle, rotate_axis[0], rotate_axis[1], rotate_axis[2]);
    drawModel();
    ...
    Hope that helps.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2001
    Location
    Concord, CA, USA
    Posts
    19

    Re: rotation & display

    Thanks for your answer,
    Yes, I am able to display the data in my window, but I need to rotate it around it's own axis. I cannot use rotatef method as it rotates the model around global origin.

    I tried to rotate the camera, but it is not so elgant.

    Please help!
    R.B

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,576

    Re: rotation & display

    The method ffish proposed is essentially correct. You can use glRotatef exactly as described and it will function correctly.

    What glRotatef does is multiply the current matrix by a rotation matrix. If the current matrix transforms objects from its local model coordinate system to camera coordinates, then multiplying a rotation matrix will rotate the object in its own local space, then transform to camera space.

  5. #5
    Junior Member Newbie
    Join Date
    Apr 2001
    Location
    Concord, CA, USA
    Posts
    19

    Re: rotation & display

    Hi, here is the code:-

    #include <stdio.h>
    #include <iostream.h>

    #include <ipm\CsaVector3D.h>
    #include "GL/glut.h"

    typedef struct
    {
    CsaVector3D vertex[3];
    } triangle;

    triangle *tri;
    int nTriangles;

    CsaVector3D min, max;

    enum {FILL, WIRE};
    int rendermode = WIRE;

    static float transx = 0.0, transy = 0.0 , rotx = 0, roty = 0;
    static int ox = -1, oy = -1;
    static int mot = 0;
    #define PAN 1
    #define ROT 2

    void menu(int selection)
    {
    rendermode = selection;
    glutPostRedisplay();
    }

    void initDisplay()
    {
    GLfloat lightpos[] = {50.f, 50.f, 20.f, 1.f};
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
    GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
    GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

    // PROJECTION
    glMatrixMode(GL_PROJECTION);

    CsaVector3D dis = max - min;
    CsaVector3D cen = min + dis/2.0;
    GLdouble left = cen[0] - dis[0];
    GLdouble right = cen[0] + dis[0];
    GLdouble bottom = cen[1] - dis[1];
    GLdouble top = cen[1] + dis[1];
    GLdouble zNear = dis[2];
    GLdouble zFar = zNear + 3*dis[2];

    glLoadIdentity();
    glOrtho(left, right, bottom, top, zNear, zFar);
    //glFrustum(-200., 200., -200., 200., 320., 640.);

    // MODEL VIEW
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* turn on features */
    glEnable(GL_DEPTH_TEST);

    /* turn on spot light */
    //glEnable(GL_LIGHTING);
    //glEnable(GL_LIGHT0);

    /* place light 0 in the right place */
    //glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

    glClearColor(.0f, .0f, .0f, .0f);
    }

    void drawTriangles()
    {
    glBegin(GL_TRIANGLES);

    for(int i=0;i<nTriangles;i++)
    {
    CsaVector3D vec = tri[i].vertex[0];
    glVertex3d(vec[0], vec[1], vec[2]);
    vec = tri[i].vertex[1];
    glVertex3d(vec[0], vec[1], vec[2]);
    vec = tri[i].vertex[2];
    glVertex3d(vec[0], vec[1], vec[2]);
    }

    glEnd();

    }

    void drawscene()
    {
    glPushMatrix();

    CsaVector3D dis = max - min;
    CsaVector3D cen = min + dis/2.0;
    glTranslated(0, 0, transx * transy - cen[2] - 2*dis[2]);
    cout << "trans = " << transx * transy - cen[2] << endl;

    //gluLookAt(cos(roty),sin(rotx),0, 0,0,-1, 0,1,0);

    glRotatef(roty, 0.0, 1.0, 0.0);
    glRotatef(rotx, 1.0, 0.0, 0.0);
    glColor3f(1.0f, 0.0f, 0.f);
    drawTriangles();

    glPopMatrix();
    }

    /* Called when window needs to be redrawn */
    void redraw()
    {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    switch(rendermode) {
    case FILL:
    drawscene();
    break;
    case WIRE: /* basic wireframe mode */
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    drawscene();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    break;
    }
    if(glGetError()) /* to catch programming errors; should never happen */
    printf("Oops! I screwed up my OpenGL calls somewhere\n");

    glutSwapBuffers();
    }


    void key(unsigned char key, int x, int y)
    {
    if(key == '\033')
    exit(0);
    }

    void pan(const int x, const int y)
    {

    transx += (x-ox)/10.;
    transy -= (y-oy)/10.;
    ox = x; oy = y;
    glutPostRedisplay();
    }

    void rotate(const int x, const int y)
    {
    rotx += (y-oy) / 60.0;
    if (rotx > 360.) rotx -= 360.;
    else if (rotx < -360.) rotx += 360.;
    roty += (x-ox) / 60.0;
    if (roty > 360.) roty -= 360.;
    else if (roty < -360.) roty += 360.;
    ox = x; oy = y;
    glutPostRedisplay();
    }

    void motion(int x, int y)
    {
    if (mot == PAN) pan(x, y);
    else if (mot == ROT) rotate(x,y);
    }

    void mouse(int button, int state, int x, int y)
    {

    /* hack for 2 button mouse */
    //if (button == GLUT_LEFT_BUTTON && glutGetModifiers() & GLUT_ACTIVE_SHIFT)
    //button = GLUT_MIDDLE_BUTTON;

    if(state == GLUT_DOWN) {
    switch(button) {
    case GLUT_LEFT_BUTTON:
    mot = ROT;
    motion(ox = x, oy = y);
    break;
    case GLUT_MIDDLE_BUTTON:
    mot = ROT;
    motion(ox = x, oy = y);
    break;
    case GLUT_RIGHT_BUTTON:
    mot = PAN;
    motion(ox = x, oy = y);
    break;
    }
    } else if (state == GLUT_UP) {
    mot = 0;
    }
    }

    void getBounds(CsaVector3D &min, CsaVector3D &max)
    {
    CsaVector3D vec = tri[0].vertex[0];
    min = max = vec;

    cout << "init=" << min << "," << max << endl;
    for(int i=0; i < nTriangles; i++)
    {
    for(int k=0;k<3;k++)
    {
    vec = tri[i].vertex[k];
    for(int j=0; j<3 ; j++)
    {
    if(min[j] > vec[j]) min[j] = vec[j];
    if(max[j] < vec[j]) max[j] = vec[j];
    }
    }
    }
    cout << "final=" << min << "," << max << endl;
    }

    /* Parse arguments, and set up interface between OpenGL and window system */
    void glDisplay(triangle *triangles, int nTri)
    {
    if(triangles == NULL) return;

    tri = triangles;
    nTriangles = nTri;

    getBounds(min, max);

    //glutInit(&argc, argv);
    glutInitWindowSize(512, 512);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow("triangle display");
    glutDisplayFunc(redraw);
    glutKeyboardFunc(key);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);

    glutCreateMenu(menu);
    glutAddMenuEntry("Solid Fill", FILL);
    glutAddMenuEntry("Wireframe", WIRE);
    //glutAttachMenu(GLUT_RIGHT_BUTTON);

    initDisplay();

    glutMainLoop();
    }

    void main(int argc, char *argv[])
    {
    CsaVector3D offsetVec = CsaVector3D(100,200,300);
    triangle *t = (triangle *)malloc(sizeof(triangle) * 4);

    t[0].vertex[0] = CsaVector3D(0,0,0) - offsetVec;
    t[0].vertex[1] = CsaVector3D(100,0,0) - offsetVec;
    t[0].vertex[2] = CsaVector3D(50,50,50) - offsetVec;

    t[1].vertex[0] = CsaVector3D(50,50,50) - offsetVec;
    t[1].vertex[1] = CsaVector3D(0,0,100) - offsetVec;
    t[1].vertex[2] = CsaVector3D(0,0,0) - offsetVec;

    t[2].vertex[0] = CsaVector3D(50,50,50) - offsetVec;
    t[2].vertex[1] = CsaVector3D(0,0,100) - offsetVec;
    t[2].vertex[2] = CsaVector3D(100,0,100) - offsetVec;

    t[3].vertex[0] = CsaVector3D(50,50,50) - offsetVec;
    t[3].vertex[1] = CsaVector3D(100,0,100) - offsetVec;
    t[3].vertex[2] = CsaVector3D(100,0,0) - offsetVec;

    glDisplay(t, 4);
    }
    R.B

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Oct 2000
    Location
    Fargo, ND
    Posts
    1,755

    Re: rotation & display

    I didn't look at all the code, but I think I understand what your problem is. Are you saying that the data for your model is not centered around the origin? That is, the "center" of the model about which you want to rotate is not at the origin. If that is the case you can do something like so...

    DoAnyCameraLikeTransformations();

    glTranslate(center.x, center.y, center.z);
    glRotate(whatever...);
    glTranslate(-center.x, -center.y, -center.z);

    Esentially what this does is to translate your model to the origin, where you can then correctly do your rotations, and then translate it back to it's proper location.

    Now for your actual rotations, I notice you are rotating separately about the x and y axes. You are probably going to run into something called "gimbal lock." Do a search on it for ways to avoid that. In short, it will matter which order you do the rotations, and there are times when you do things in a certain order, the rotation will not appear correct.
    Deiussum
    Software Engineer and OpenGL enthusiast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •