help pls - rotating a 3d object

Member
Posts: 36
Joined: 2009.02
Post: #16
ThemsAllTook Wrote:This really isn't the right way to think of it. When you apply a transformation, you're transforming the world's coordinate system, not your object coordinates. When you send vertices to GL, they're relative to the current world transformation.
You're right. And this way, the order of transformations makes sense. I tend to think that I operate on the object coordinate system because I always deal with objects that are not attached to other objects. If I wanted to build a solar system or a robot arm with its articulations, it wouldn't work at all (or it would be harder to understand).

jfhtgui Wrote:thanks. Yeah, I did try the translation before. But guess it was the removal of the offset to the vertices that really saw some progress (thanks!)... Now my object becomes "more" visible - although there's still clipping. Am I missing something?
Check your zNear and zFar clipping planes. In OpenGL you specify two depth planes along the Z axis so that objects outside of it are not drawn. Are you using parallel or perspective projection? Check the Z values you're passing to glOrtho (parallel) or glFrustum (perspective). Sounds like this is causing the clipping.
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #17
miq01 Wrote:Check your zNear and zFar clipping planes. In OpenGL you specify two depth planes along the Z axis so that objects outside of it are not drawn. Are you using parallel or perspective projection? Check the Z values you're passing to glOrtho (parallel) or glFrustum (perspective). Sounds like this is causing the clipping.

got it, thanks. I never knew that these even existed as clipping planes..
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #18
Najdorf Wrote:I see a number of possible problems:

Did you set your GL_PROJECTION matrix? if it's identity (i.e. you didn't set it) it only draws values with z between -1 and 1 (and also doesn't look 3d) .

You need to set up a 3d projection matrix, with normal opengl you use gluPerspective, glu is not in opengl ES but glu is open source now

Code:
...

( you can find the full glu implementation by sgi included with the mesa library download http://www.mesa3d.org/ )

ok, got it. thanks. I had to convert those GLdouble references to GLfloat, + do a few other things, but that code compiled just fine.

Quote:so before calling glMatrixMode(GL_MODELVIEW); you should call glMatrixMode(GL_PROJECTION); gluPerspective( 45.0 <camera angle>, 4/3.0 <screen ratio>, 0.1 <closest thing you draw>, 20.0<furthest thing you draw> );

remeber at this point it draws only stuff with positive z, between 0.1 and 20.

Is that how it works? I'm reading http://www.opengl.org/documentation/spec...ctive.html now, and I'm confused.

zNear and zFar represent "the distance from the viewer to the near(/far) clipping plane (always positive)". But what is the viewer's actual z position? And if these 2 z values are supposed to be always positive (and if as you say, only stuff between the 2 z values are drawn), then how do I draw stuff with negative z?

Anyway, as an experiment I tried changing my z values (to 1, and 11). But I still get nothing if I call this gluPerspective... Seems like I'm not doing something right with gluPerspective. See below - I've removed the rotate temporarily in order to see if the call to gluPerspective is giving a problem. It is. Once I remove it, I can see the object again.


Code:
            glMatrixMode(GL_PROJECTION);
            gluPerspective(45.0, 4/3.0, 0.1, 20.0);

            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glTranslatef(xOffset, yOffset, 0.0f);
            //glRotatef(1.0f, 0.0f, 1.0f, 0.0f);


Quote:Also with your code you are rotating also the offset of your object, not the object around its axis, as miq01 sais.

Right. I've fixed that by translating before rotating now.
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #19
There might be a problem with your model, try with a cube or something.

on top of gluPerspective you also need gluLookAt if you want to position the camera Rasp

If camera is pointing backwards (to 0,0,-1) then you will be able to see the stuff with z between -0.1 and -20 (the znear zfar of gluPerspective)


Code:
static void cross(float v1[3], float v2[3], float result[3])
{
    result[0] = v1[1]*v2[2] - v1[2]*v2[1];
    result[1] = v1[2]*v2[0] - v1[0]*v2[2];
    result[2] = v1[0]*v2[1] - v1[1]*v2[0];
}


static void normalize(float v[3])
{
    float r;

    r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
    if (r == 0.0) return;

    v[0] /= r;
    v[1] /= r;
    v[2] /= r;
}


gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
      GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
      GLdouble upz)
{
    float forward[3], side[3], up[3];
    GLfloat m[4][4];

    forward[0] = centerx - eyex;
    forward[1] = centery - eyey;
    forward[2] = centerz - eyez;

    up[0] = upx;
    up[1] = upy;
    up[2] = upz;

    normalize(forward);

    /* Side = forward x up */
    cross(forward, up, side);
    normalize(side);

    /* Recompute up as: up = side x forward */
    cross(side, forward, up);

    __gluMakeIdentityd(&m[0][0]);
    m[0][0] = side[0];
    m[1][0] = side[1];
    m[2][0] = side[2];

    m[0][1] = up[0];
    m[1][1] = up[1];
    m[2][1] = up[2];

    m[0][2] = -forward[0];
    m[1][2] = -forward[1];
    m[2][2] = -forward[2];

    glMultMatrixf(&m[0][0]);
    glTranslated(-eyex, -eyey, -eyez);
}

so if you want to look backwards from 0,0,0 to 0,0,-1 you would call

glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, 4/3.0, 0.1, 20.0);
gluLookAt(0,0,0,0,0,-1,0,1,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(xOffset, yOffset, 0.0f);
//glRotatef(1.0f, 0.0f, 1.0f, 0.0f);

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #20
You don't have to use gluLookAt to move the "camera". gluLookAt is just a UVN matrix rotation, plus a translation tacked on. You can just as well use any other method of transforming, like glTranslate, etc., (although you'll have a problem with gimbal lock if you don't use quats and you want to rotate three axes at once, which a UVN rotation doesn't have a problem with). The viewpoint (or camera if you want to call it that) initially sits at 0, 0, 0, looking down the negative z axis. You merely translate and rotate the scene backwards of where you want it to go to move the "camera". It's funky to grasp this concept at first -- moving the scene away from the camera, like glTranslate(0.0f, 0.0f, -7.0f) would be the same thing as moving the camera backwards, or glTranslate(0.0f, 0.0f, 7.0f) (which you can't do because, remember, there is no "camera").

Since there is no built-in gluPerspective on iPhone (and assuming this is running on an iPhone since that's the sub-forum we're in), that means you must be using custom code for it, so make sure that is correct.

Also, gluPerspective(45.0, 4/3.0, 0.1, 20.0); is rather modest. If I'm having trouble seeing objects or there's funky clipping going on, I'd pump that up to like gluPerspective(45.0, 4/3.0, 0.01, 2000.0);
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #21
Najdorf Wrote:There might be a problem with your model, try with a cube or something.

on top of gluPerspective you also need gluLookAt if you want to position the camera Rasp

ok. So I guess 2 things will always define what the camera can see then? Camera position, and gluPerspective.

Quote:If camera is pointing backwards (to 0,0,-1) then you will be able to see the stuff with z between -0.1 and -20 (the znear zfar of gluPerspective)


Code:
...

so if you want to look backwards from 0,0,0 to 0,0,-1 you would call

glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, 4/3.0, 0.1, 20.0);
gluLookAt(0,0,0,0,0,-1,0,1,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(xOffset, yOffset, 0.0f);
//glRotatef(1.0f, 0.0f, 1.0f, 0.0f);

that's fine, but I thought the default position of the camera is at 0,0,0, looking down the negative z-axis?

Anyway, thanks a lot for your help. Really appreciate it. Unfortunately, this thing just isn't working out...
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #22
AnotherJake Wrote:You don't have to use gluLookAt to move the "camera". gluLookAt is just a UVN matrix rotation, plus a translation tacked on. You can just as well use any other method of transforming, like glTranslate, etc., (although you'll have a problem with gimbal lock if you don't use quats and you want to rotate three axes at once, which a UVN rotation doesn't have a problem with).

woah. Most of that went over my head Smile But got it that I dont necessarily have to use gluLookAt to move the camera. Thanks.

Quote:The viewpoint (or camera if you want to call it that) initially sits at 0, 0, 0, looking down the negative z axis.

yeah. So I guess it should see stuff at z -1.0, and z -11.0?

Quote:You merely translate and rotate the scene backwards of where you want it to go to move the "camera". It's funky to grasp this concept at first -- moving the scene away from the camera, like glTranslate(0.0f, 0.0f, -7.0f) would be the same thing as moving the camera backwards, or glTranslate(0.0f, 0.0f, 7.0f) (which you can't do because, remember, there is no "camera").

Since there is no built-in gluPerspective on iPhone (and assuming this is running on an iPhone since that's the sub-forum we're in),

yes, it is!

Quote:that means you must be using custom code for it, so make sure that is correct.

Smile well, I'm using what Najdorf provided. I trust that it is correct?

Quote:Also, gluPerspective(45.0, 4/3.0, 0.1, 20.0); is rather modest. If I'm having trouble seeing objects or there's funky clipping going on, I'd pump that up to like gluPerspective(45.0, 4/3.0, 0.01, 2000.0);

thanks. Just tried this, but again, no luck...
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #23
AnotherJake Wrote:Also, gluPerspective(45.0, 4/3.0, 0.1, 20.0); is rather modest. If I'm having trouble seeing objects or there's funky clipping going on, I'd pump that up to like gluPerspective(45.0, 4/3.0, 0.01, 2000.0);

Well if you have objects that are 2000 units away and also need to draw stuff that is as close as 0.01 units then fine, still the bigger the zfar/znear ratio the more you lose in z-buffer precision.

@jfhtgui the code is copy pasted from Silicon Graphic's (the developers of OpenGL) own implementation of glu so I should guess it's good. True you can replace gluplacecamera just by rotating and translating, gluLookat is more intuitive imo.

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #24
jfhtgui Wrote:Smile well, I'm using what Najdorf provided. I trust that it is correct?
Sorry, I forgot about the stuff on the first page. Yes, it looks like it should work. My version is a lot less involved. I suppose you could try it just to be sure, but I doubt it will solve the problem.

Code:
void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
    GLfloat xmin, xmax, ymin, ymax;

    ymax = zNear * tanf(fovy * M_PI / 360.0f);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;


    glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
}

We'll get to the bottom of this. I need to go back over this thread when I get a chance in a little bit and see if I can spot anything.

Najdorf Wrote:Well if you have objects that are 2000 units away and also need to draw stuff that is as close as 0.01 units then fine, still the bigger the zfar/znear ratio the more you lose in z-buffer precision.

Of course you lose depth precision, but if you're trying to find objects you can't see, there's nothing wrong with cranking things up temporarily (I wouldn't be afraid to crank it to 20,000 for that matter!). Regardless, it depends on the scene you're drawing as to whether the precision will affect you or not. Obviously, the smaller the better, but 0.01 to 2000 isn't ridiculous in my experience.
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #25
Najdorf Wrote:@jfhtgui the code is copy pasted from Silicon Graphic's (the developers of OpenGL) own implementation of glu so I should guess it's good. True you can replace gluplacecamera just by rotating and translating, gluLookat is more intuitive imo.

yup. Thanks.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #26
Oh yes, don't get me wrong, there is absolutely nothing wrong with using gluLookAt -- I use it myself! I was just pointing out that you don't *have* to use gluLookAt. A person should know that you can just move the scene back a bit by using glTranslatef(0.0f, 0.0f, -7.0f) and know immediately that you just moved the camera in a way that might help make an object sitting at the origin visible (assuming it's small enough). I can't count how many times I've drawn an object and couldn't figure out where it was because I forgot to move the object (or camera) and was actually inside the object.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #27
Alright, I figured out what's up. Since you are generating your geometry dynamically you were essentially pre-transforming your vertices. This is sloppy, but it'll get you back in business. I have it set up so your drag will rotate a little too, so you can look at it right away:

Code:
GLfloat z1 = -1.0f;
    GLfloat z2 = -11.0f;

    glClearDepthf(1.0f);
    glClear(GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, 4.0f/3.0f, 1.0f, 20.0f);
    //glOrthof(-1.5f, 1.5f, -2.0f, 2.0f, 1.0f, 20.0f); // <-- you can do this instead
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -10.0f);
    glRotatef(xradius, 0.0f, 1.0f, 0.0f); // auto rotate based on drag using xradius
    glScalef(yradius * 0.1f, yradius * 0.1f, 1.0f);
    
    GLfloat vertices[2000];
    
    vertices[0] = 0.0f;
    vertices[1] = 0.0f;
    for (int i = 1; i <= 90; i+=1)
    {
        vertices[i*3] = cos(degreesToRadian(i));
        vertices[i*3+1] = sin(degreesToRadian(i));
        vertices[i*3+2] = z1;
        
        thickness[i*6] = thickness[i*6+3] = vertices[i*3];
        thickness[i*6+1] = thickness[i*6+4] = vertices[i*3+1];
        thickness[i*6+2] = z1;
        thickness[i*6+5] = z2;
    }
    glVertexPointer (3, GL_FLOAT, 0, vertices);
    
    glDrawArrays (GL_TRIANGLE_FAN, 0, 91);

    glVertexPointer (3, GL_FLOAT, 0, thickness);
    glDrawArrays (GL_TRIANGLE_STRIP, 0, 180);
    
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #28
AnotherJake Wrote:Alright, I figured out what's up. Since you are generating your geometry dynamically you were essentially pre-transforming your vertices. This is sloppy, but it'll get you back in business. I have it set up so your drag will rotate a little too, so you can look at it right away:

Code:
...

thanks, AnotherJake! this really got the thing going. I dont understand all of it, though. One question: how do you get the rotation to be done at the center of the triangle fan? ie. vertices[0], vertices[1] ?
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #29
jfhtgui Wrote:thanks, AnotherJake! this really got the thing going. I dont understand all of it, though. One question: how do you get the rotation to be done at the center of the triangle fan? ie. vertices[0], vertices[1] ?

Oh boy... I don't know how to answer that fully. Hopefully someone else can do better, but I'll take a stab at it:

The center you were providing previously was based on mouse coordinates. That is, if the user tapped at 50, 75, all of the rest of your pie chart's vertices were calculated around 50, 75. That doesn't work well at all when you're dealing with graphics transforms. The geometry (aka "model") must be specified in reference to an origin (0, 0, 0). This means you'd be describing coordinates in "model space". If you specify the coordinates around 50, 75, then you intrinsically added a transform just like glTranslate(50.0f, 75.0f, 0.0f), which wasn't what you were expecting, and had the effect of rotating the object out of view at the slightest twitch. The pie chart was positioned at the end of a long pole, even though it appeared in view. It's like you thought the baseball was being rotated in your hand, but the baseball was attached to the end of a bat and you rotated the bat, not the ball. That's why it disappeared out of the viewing space with such a low angle input.

I also took out your calculation of the model's size based on the radius, and instead made the vertices to assume a radius of 1.0 where you use cos/sin, to help highlight the issue. You can change that back to multiplying by the radius again if you wish, but I used glScalef instead as a demonstration.

This is probably all really confusing to you, but it's one of the steepest parts of the OpenGL learning curve. Like I said, I hope someone else can jump in and help make it clearer. Smile
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2009.03
Post: #30
AnotherJake Wrote:Oh boy... I don't know how to answer that fully. Hopefully someone else can do better, but I'll take a stab at it:

The center you were providing previously was based on mouse coordinates. That is, if the user tapped at 50, 75, all of the rest of your pie chart's vertices were calculated around 50, 75. That doesn't work well at all when you're dealing with graphics transforms. The geometry (aka "model") must be specified in reference to an origin (0, 0, 0). This means you'd be describing coordinates in "model space". If you specify the coordinates around 50, 75, then you intrinsically added a transform just like glTranslate(50.0f, 75.0f, 0.0f), which wasn't what you were expecting, and had the effect of rotating the object out of view at the slightest twitch. The pie chart was positioned at the end of a long pole, even though it appeared in view. It's like you thought the baseball was being rotated in your hand, but the baseball was attached to the end of a bat and you rotated the bat, not the ball. That's why it disappeared out of the viewing space with such a low angle input.

thanks. I more or less get that (to rotate an object about its own center, you must somehow (and this, to me, is the confusing part!) draw it around "the current" 0,0,0).

I have a few other questions, though:
- how does this origin end up being somewhere in the center of the screen? I can understand how that might be the case if i use a glTranslatef (xOffset, yOffset, 0), and then draw around the origin, but for this one? the glTranslatef has 0 x, and 0 y translation... Shouldnt the object be drawn around the lower left corner of the screen then (this is [0,0]???) This is number 1.
- number 2 is this, which was what I was trying to ask about rotation to be done at the center of the triangle fan: when I move my mouse along x right now, I'm expecting to see the center of the fan stay. But in fact, it doesnt. Why is this so? and what's causing it?


Quote:I also took out your calculation of the model's size based on the radius, and instead made the vertices to assume a radius of 1.0 where you use cos/sin, to help highlight the issue. You can change that back to multiplying by the radius again if you wish, but I used glScalef instead as a demonstration.

thanks. I dont really get that right now - but the point about radius being 1.0.. yeah, that really helped. I was just begining to think "so what happened to the radius? why shouldnt we multiply by the radius?" (sometimes "*1" can be so easily forgotten and missed...)
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Rotating a clipped Texture tfifriday 1 1,711 Feb 3, 2009 06:00 AM
Last Post: godexsoft