HomeForumsWhat's newResources 
 
 
Help the Newbie
Quick Man - Oct 23, 2005
   Quick Man Oct 23, 2005 
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 Oct 23, 2005 
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.