# Help the Newbie

#### Quick Man

I've been writing this code for polygon.c for the past week or so and I can't shift some bugs, so I hoped I'd be able to get some experienced eyes cast over it. Thanks in advance. =P

The intent is to generate a landscape from a series of heights. (There may be some small bugs in it because I recently unwrapped an array of arrays to form a single array to make my life easier and haven't fiddled everything else to compensate.)

Code:
``````#include "sgl.h"

// function to calculate the normalised cross product of two vectors - why is this not part of the SGL already?

VECTOR slCrossProduct(VECTOR u, VECTOR v)

{

VECTOR cross =

{

slMulFX(u[Y],v[Z]) - slMulFX(u[Z],v[Y]),

slMulFX(u[Z],v[X]) - slMulFX(u[X],v[Z]),

slMulFX(u[X],v[Y]) - slMulFX(u[Y],v[X]),

};

// normalise X

if (cross[X] > toFIXED(0.0)) {cross[X] = toFIXED(1.0);}

else {cross[X] = toFIXED(-1.0);};

// normalise Y

if (cross[Y] > toFIXED(0.0)) {cross[Y] = toFIXED(1.0);}

else {cross[Y] = toFIXED(-1.0);};

// normalise Z

if (cross[Z] > toFIXED(0.0)) {cross[Z] = toFIXED(1.0);}

else {cross[Z] = toFIXED(-1.0);}

return cross;

}

// counters for loops

Uint32 m, n, t, u;

// size of grid in vertices

Uint32 nx = 5;

Uint32 nz = 5;

Uint32 r = 4;

Uint32 s = 4;

// size of grid in coordinate units

FIXED lx = toFIXED(50.0);

FIXED lz = toFIXED(50.0);

// elevation of each vertex

FIXED height[] =

{

{toFIXED(5.0), toFIXED(4.0), toFIXED(3.0), toFIXED(2.0), toFIXED(1.0),

toFIXED(4.0), toFIXED(3.5), toFIXED(3.0), toFIXED(2.5), toFIXED(2.0),

toFIXED(3.0), toFIXED(3.0), toFIXED(3.0), toFIXED(3.0), toFIXED(3.0),

toFIXED(2.0), toFIXED(2.5), toFIXED(3.0), toFIXED(3.5), toFIXED(4.0),

toFIXED(1.0), toFIXED(2.0), toFIXED(3.0), toFIXED(4.0), toFIXED(5.0)},

};

// vertex data

POINT vert[];

// normal vector data

NORMAL norm[];

// polygon data

POLYGON poly[];

// attribute data

ATTR attr[];

VECTOR v1,v2;

for (n = 0; n < nz; n++)

{

for(m = 0; m < nx; m++)

{

vert[q] = {slMulFX(toFIXED(m/nx), lx), height[((n-1)*nz)+m], slMulFX(toFIXED(n/nz), lz};

};

}

for(t = 0; t < r*s; t++)

{

v1 = vert[t+1] - vert[t];

v2 = vert[t+nz] - vert[t];

norm[t]  = slCrossProduct(v1,v2);

poly[t]  = {norm[t], VERTICES(t, t+1, t+nz, t+nz+1)};

// dummy attribute data for now

attr[t] = ATTRIBUTE(Dual_Plane, SORT_CEN, No_Texture, C_RGB(16, 16, 16), No_Gouraud, MESHoff, sprPolygon, No_Option);

}

// polygon model data - this bit only works if everything else works (fingers crossed!)

PDATA PD_SCAPE1 =

{

vert, sizeof(vert)/sizeof(POINT),

poly, sizeof(poly)/sizeof(POLYGON),

attr,

};``````

It looks horrible because it was formatted for Notepad, because I was using that when drafting it. HTML is not kind to it.

#### RockinB

Staff member
Hi Quick Man!

The function slCrossProduct(VECTOR u, VECTOR v) is wrong in at least 2 concerns:

Returning a pointer to local variable VECTOR cross does not work to return the result, as the content will be lost after the function exits.

slCrossProduct(VECTOR u, VECTOR v, VECTOR cross)

The normalization is wrong, it will overwrite the computed cross vector completely.

Normalization is done when

FIXED len = slMulFX(cross[X], cross[X]) + slMulFX(cross[Y], cross[Y]) + slMulFX(cross[Z], cross[Z]) > toFIXED(1.0)

then it's normalized this way:

len = slSquartFX(l);

cross[X] = slDivFX(len, cross[X]);

cross[Y] = slDivFX(len, cross[Y]);

cross[Z] = slDivFX(len, cross[Z]);

But that's just the mathematics behind, I would try to use a CORDIC algorithm, maybe I did it somewhere.

// function to calculate the normalised cross product of two vectors - why is this not part of the SGL already?

VECTOR slCrossProduct(VECTOR u, VECTOR v)

Oh, it does got a function for this:

Code:
``````******************************************************************************

void slNormalVector(VECTOR a, b, c, ans)

******************************************************************************

Function:

Computes a vector (unit normal vector) which intersects 2 vectors (b->a, b->c)

specified by 3 points.

To reverse the way of vectors, sets the 3 points in the order of b, a, and c.****** Changes ***************``````

But I don't know if the vector is already normalized.

Okay, let's go on in the code...

These vectors have no length in initialization, I inserted the length here:

(note: you can't use global variables to set the length, that's why #define)

Code:
``````#define GRID_X 5

#define GRID_Z 5

#define NB_POINT   GRID_X*GRID_Z

#define NB_POLYGON (GRID_X-1)*(GRID_Z-1)

// vertex data

POINT vert[NB_POINT];

// normal vector data

NORMAL norm[NB_POLYGON];

// polygon data

POLYGON poly[NB_POLYGON];

// attribute data

ATTR attr[NB_POLYGON];``````

You can do this assignment only when declaring variables:

Code:
``````for (n = 0; n < nz; n++)

{

for(m = 0; m < nx; m++)

{

vert[q] = {slMulFX(toFIXED(m/nx), lx), height[((n-1)*nz)+m], slMulFX(toFIXED(n/nz), lz};

};

}``````

Furthermore, this will potentially not compute what you want: toFIXED(m/nx). The macro toFIXED() is used best with constant arguments, not variables. So the C compiler can do the floating point computation.

A POINT has got no 4th component.

And this here: height[((n-1)*nz)+m] results in a negative index when n = 0.

Code:
``````#define GRID_SIZE_X  50.0

#define GRID_SIZE_Z  50.0

#define UNIT_SIZE_X  toFIXED(GRID_SIZE_X / GRID_X)

#define UNIT_SIZE_Z  toFIXED(GRID_SIZE_Z / GRID_Z)

FIXED lx = toFIXED(GRID_SIZE_X);

FIXED lz = toFIXED(GRID_SIZE_Y);

FIXED myZ = toFIXED(0);

Uint32 o = 0;

for (n = 0; n < nz; n++, myZ += UNIT_SIZE_Z)

{

FIXED myX = toFIXED(0);

for(m = 0; m < nx; m++, myX += UNIT_SIZE_X)

{

vert[q][X] = myX;

vert[q][Y] = height[o++];

vert[q][Z] = myZ;

};

}``````

Now let's have a look on this:

Code:
``````for(t = 0; t < r*s; t++)

{

v1 = vert[t+1] - vert[t];

v2 = vert[t+nz] - vert[t];

norm[t]  = slCrossProduct(v1,v2);

poly[t]  = {norm[t], VERTICES(t, t+1, t+nz, t+nz+1)};

// dummy attribute data for now

attr[t] = ATTRIBUTE(Dual_Plane, SORT_CEN, No_Texture, C_RGB(16, 16, 16), No_Gouraud, MESHoff, sprPolygon, No_Option);

}``````

First VECTOR is a structure, you can't apply integer arithmetics like done here:

Code:
``````v1 = vert[t+1] - vert[t];

v2 = vert[t+nz] - vert[t];

norm[t]  = slCrossProduct(v1,v2);``````

But when you use slNormalVector(), you don't have to care about component wise arithmetics.

Okay, I'll stop here now. Assignments for poly[t] and attr[t] are wrong, as they are declaration style.

I'm kind of confused because you mixed the declarations with code.

Replies
14
Views
2K
Replies
0
Views
3K
Replies
7
Views
744
Replies
1
Views
775
Replies
3
Views
603