help pls - rotating a 3d object

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.

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..

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.

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);

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 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.

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);

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.

jfhtgui Wrote: 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.

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.

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.

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.

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:

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] ?

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.

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...)