Archived

This topic is now archived and is closed to further replies.

CoiN

3D Problem Huge Z Increments

Recommended Posts

CoiN    122
Lo all, I don''t know if the post title made any sense but I couldn''t think of anything else. My problems is basically this: I am creating a very basic 3D Wireframe app, just for learning purposes, and I have never done any 3D before. In my 3d space the x and y co-ords are fine but for some reason the z Co-Ord is hugely out of proportion with the x and y. For instance if we have a point on a polygon and z was 1 while all the other points where z = 0 (in local co-ords), that corner would be massively extended towards the screen. I have got around this by scaling z down, but when it comes to rotation around the x or y axes, it doesn''t work as x or y may equal something like 50 and that would make z eventually equal 50. Which means the rotated polygon or whatever comes flying at the screen and through the camera. My brain is a bit dead at the moment and it is probably something stupid I am missing. Any ideas? Thanks in Advance.... Coin

Share this post


Link to post
Share on other sites
JuNC    236
It''s tricky to know what you mean without any specifics on how you''re implementing this stuff, but superficially it sounds like you''re using a very narrow field of view, or you''re simply doing it right and are not used to how the perspective warp affects space.

You''ll probably need to post the equations and values you''re trying to use to get a specific answer. Screenshots of the problem would also help.

Share this post


Link to post
Share on other sites
CoiN    122
Hi,

Thanks for the reply.

I''ll post some of the code below:

This is how I initialise my camera, it is very basic, no rotation has been implemented for the camera, it just looks straight down the Z-Axis.



// Initialise a Euler Camera

void Init_EulerCam(EulerCam *cam, Point3Dh pos, Point3Dh dir, int vp_w, int vp_h)

{
// Init the camera position

cam->Position.x = pos.x;
cam->Position.y = pos.y;
cam->Position.z = pos.z;
cam->Position.w = 1;

// Init the camera direction

cam->Direction.x = dir.x;
cam->Direction.y = dir.y;
cam->Direction.z = dir.z;
cam->Direction.w = 1;

// Init the viewport dimensions

cam->Viewport_W = vp_w;
cam->Viewport_H = vp_h;
cam->Viewport_Cx = (vp_w - 1) / 2;
cam->Viewport_Cy = (vp_h - 1) / 2;
cam->Aspect_Ratio = (float) vp_w / (float) vp_h;

// Init the viewplane

cam->Viewplane_W = 2;
cam->Viewplane_H = 2 / cam->Aspect_Ratio;

// Calculate the View distance

cam->View_Dist = 0.5 * cam->Viewplane_W * tanf(0.765);
}



This is where I transform the poly to perspective.
TVList[] is just the transformed vertex list.



// Transform Camera to Perspective

void TriPoly3D_Camera_to_Perspective(TriPoly3D *poly, EulerCam *cam)

{
int count;

// Transform the vertexes

for(count = 0; count < 3; count++)
{
poly->TVList[count].x = (cam->View_Dist * poly->TVList[count].x) / poly->TVList[count].z;
poly->TVList[count].y = (cam->View_Dist * cam->Aspect_Ratio * poly->TVList[count].y) / poly->TVList[count].z;
}
}



I am pretty certain the rotation code is okay.

Hope that is enough info.

Thanks....


Coin

Share this post


Link to post
Share on other sites
Neoteric    122
Really obvious question, sounds like verticies are passing into negative Z space, are polygons being clipped against a near plane? Translate a few hundered into Z when rotating to check your coordinate system.

Share this post


Link to post
Share on other sites
CoiN    122
Lo,

There is no clipping at all yet, but the polygons are definetly staying in front of the camera and not going behind.

I had that problem at first and spent days trying to figure out what was wrong.

Cheers for the reply,

Coin.

Share this post


Link to post
Share on other sites
JohnBolton    1372
I believe
    cam->View_Dist = 0.5 * cam->Viewplane_W *   tanf(0.765);   
should be
    cam->View_Dist = 0.5 * cam->Viewplane_W /   tanf(0.765);   
And I prefer "PI_OVER_4" instead of "0.765".

[edited by - JohnBolton on September 1, 2003 6:15:59 AM]

Share this post


Link to post
Share on other sites
CoiN    122
Thanks for the reply.

Changing that line of code only seems to make a very slight difference to the perspective.

I have an idea which will probably fix it but it will probably involve uneeded calculations.

Thanks for the help everyone, I''ll try my idea and see if it works.

Coin

Share this post


Link to post
Share on other sites
CoiN    122
Lo again,

My idea didn''t work.

I''ll post some pictures of the problem so it can be seen.

The first picture is of a square where all vertices are set to z = 2, so the square is parallel to the view screen.

http://www.chizief.co.uk/square1.jpg

The second picture, three vertices on 1 side have been set to 1, and as you can see the square stretches greatly into the background. Now I would expect this to happen if Z were a much larger number (or smaller in this case) but with a change of only 1, the distance change should be minimal.

http://www.chizief.co.uk/square2.jpg

Now this isn''t a problem until I come to rotate an object on the X or Y axes. As you can imagine if X or Y are 10 when when I rotate the object it is extending huge amounts into the distance and towards the camera, so the object looks around 500 miles long and only very thin.

I''m wondering if it is anything to do with the field of view.

Thanks....

Coin


Share this post


Link to post
Share on other sites
CoiN    122
Hi,

I'll post the matrix code, but I am sure that is fine as it rotates on the Z axis fine.

This is the function to multiply and Point (or a vector) by a 3x3 matrix, which is simply a float[3][3].



// Multiply a 3x3 Matrix by a Point3Dh

void MMul_3x3_Point3Dh(Matrix3x3 *m, Point3Dh *p, Point3Dh *result)

{
int row_count, col_count;
float sum;

// Columns

for(col_count = 0; col_count < 3; col_count++)
{
// Reset sum

sum = 0;

// Rows

for(row_count = 0; row_count < 3; row_count++)
{
sum += (p->xyzw[row_count] * m->index[row_count][col_count]);
}

// Store the result

result->xyzw[col_count] = sum;
}

}



And the 3 axis rotation matrices.

And I know I should be converting the degrees to radians just once.



// Initialise the rotation matrix X axis

Init_Matrix3x3(&mat, 1, 0, 0,
0, cosf((PI * angle) / 180), sinf((PI * angle) / 180),
0, -sinf((PI * angle) / 180), cosf((PI * angle) / 180));

// Initialise the rotation matrix Z axis

Init_Matrix3x3(&mat, cosf((PI * angle) / 180), sinf((PI * angle) / 180), 0,
-sinf((PI * angle) / 180), cosf((PI * angle) / 180), 0,
0, 0, 1);

// Initialise the rotation matrix Y axis

Init_Matrix3x3(&mat, cosf((PI * angle) / 180), 0, -sinf((PI * angle) / 180),
0, 1, 0,
sinf((PI * angle) / 180), 0, cosf((PI * angle) / 180));



These are just being used individually for now, I haven't multiplied them together or anything like that, so just take it as only one of these matrices is used.

Thanks for the reply...

Coin





[edited by - Coin on September 1, 2003 4:07:05 PM]

Share this post


Link to post
Share on other sites
Neoteric    122
instead of...

poly->TVList[count].x = (cam->View_Dist * poly->TVList[count].x) / poly->TVList[count].z;
poly->TVList[count].y = (cam->View_Dist * cam->Aspect_Ratio * poly->TVList[count].y) / poly->TVList[count].z;

try...

zr = cam->View_Dist / (poly->TVList[count].z + cam->View_Dist);
poly->TVList[count].x *= zr;
poly->TVList[count].y *= zr;

EDIT: Check cam->View_Dist is the expected value, try setting it to 300-1000 or so manually.

[edited by - Neoteric on September 1, 2003 5:58:00 PM]

Share this post


Link to post
Share on other sites
CoiN    122
Lo,

It seems that the cam->View_Dist was the problem. If I change it's value to around 100 it seems to work okay.

I'm certain I checked that as well.

Thanks Neoteric, and everyone else who replied. The help was much appreciated.

Cya

Coin

EDIT: I changed the Viewplane_W to the Viewport_W (Width of the window) in the cam->View_Dist calculation and everything is fine. I really am an idiot sometimes.



[edited by - Coin on September 2, 2003 10:12:14 AM]

Share this post


Link to post
Share on other sites