Help the Newbie

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.

Instead do this:

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.

Instead do this:

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