void rt_tri_fcylinder(void * tex, vector ctr, vector axis, apiflt rad) { vector x, y, z, tmp; double u, v, u2, v2; int j; vector p1, p2, p3, p4; vector n1, n2; z = axis; MyVNorm(&z); tmp.x = z.y - 2.1111111; tmp.y = -z.z + 3.14159267; tmp.z = z.x - 3.915292342341; MyVNorm(&z); MyVNorm(&tmp); MyVCross(&z, &tmp, &x); MyVNorm(&x); MyVCross(&x, &z, &y); MyVNorm(&y); for (j=0; j<CYLFACETS; j++) { u = rad * sin((6.28 * j) / (CYLFACETS - 1.0)); v = rad * cos((6.28 * j) / (CYLFACETS - 1.0)); u2 = rad * sin((6.28 * (j + 1.0)) / (CYLFACETS - 1.0)); v2 = rad * cos((6.28 * (j + 1.0)) / (CYLFACETS - 1.0)); p1.x = p1.y = p1.z = 0.0; p4 = p3 = p2 = p1; MyVAddS(u, &x, &p1, &p1); MyVAddS(v, &y, &p1, &p1); n1 = p1; MyVNorm(&n1); MyVAddS(1.0, &ctr, &p1, &p1); MyVAddS(u2, &x, &p2, &p2); MyVAddS(v2, &y, &p2, &p2); n2 = p2; MyVNorm(&n2); MyVAddS(1.0, &ctr, &p2, &p2); MyVAddS(1.0, &axis, &p1, &p3); MyVAddS(1.0, &axis, &p2, &p4); rt_stri(tex, p1, p2, p3, n1, n2, n1); rt_stri(tex, p3, p2, p4, n1, n2, n2); } }
void rt_tri_ring(void * tex, vector ctr, vector norm, apiflt a, apiflt b) { vector x, y, z, tmp; double u, v, u2, v2; int j; vector p1, p2, p3, p4; vector n1, n2; z = norm; MyVNorm(&z); tmp.x = z.y - 2.1111111; tmp.y = -z.z + 3.14159267; tmp.z = z.x - 3.915292342341; MyVNorm(&z); MyVNorm(&tmp); MyVCross(&z, &tmp, &x); MyVNorm(&x); MyVCross(&x, &z, &y); MyVNorm(&y); for (j=0; j<RINGFACETS; j++) { u = sin((6.28 * j) / (RINGFACETS - 1.0)); v = cos((6.28 * j) / (RINGFACETS - 1.0)); u2 = sin((6.28 * (j + 1.0)) / (RINGFACETS - 1.0)); v2 = cos((6.28 * (j + 1.0)) / (RINGFACETS - 1.0)); p1.x = p1.y = p1.z = 0.0; p4 = p3 = p2 = p1; MyVAddS(u, &x, &p1, &p1); MyVAddS(v, &y, &p1, &p1); n1 = p1; MyVNorm(&n1); MyVAddS(a, &n1, &ctr, &p1); MyVAddS(b, &n1, &ctr, &p3); MyVAddS(u2, &x, &p2, &p2); MyVAddS(v2, &y, &p2, &p2); n2 = p2; MyVNorm(&n2); MyVAddS(a, &n2, &ctr, &p2); MyVAddS(b, &n2, &ctr, &p4); rt_stri(tex, p1, p2, p3, norm, norm, norm); rt_stri(tex, p3, p2, p4, norm, norm, norm); } }
static void rt_sheightfield(void * tex, vector ctr, int m, int n, apiflt * field, apiflt wx, apiflt wy) { vector * vertices; vector * normals; vector offset; apiflt xinc, yinc; int x, y, addr; vertices = (vector *) malloc(m*n*sizeof(vector)); normals = (vector *) malloc(m*n*sizeof(vector)); offset.x = ctr.x - (wx / 2.0); offset.y = ctr.z - (wy / 2.0); offset.z = ctr.y; xinc = wx / ((apiflt) m); yinc = wy / ((apiflt) n); /* build vertex list */ for (y=0; y<n; y++) { for (x=0; x<m; x++) { addr = y*m + x; vertices[addr] = rt_vector( x * xinc + offset.x, field[addr] + offset.z, y * yinc + offset.y); } } /* build normals from vertex list */ for (x=1; x<m; x++) { normals[x] = normals[(n - 1)*m + x] = rt_vector(0.0, 1.0, 0.0); } for (y=1; y<n; y++) { normals[y*m] = normals[y*m + (m-1)] = rt_vector(0.0, 1.0, 0.0); } for (y=1; y<(n-1); y++) { for (x=1; x<(m-1); x++) { addr = y*m + x; normals[addr] = rt_vector( -(field[addr + 1] - field[addr - 1]) / (2.0 * xinc), 1.0, -(field[addr + m] - field[addr - m]) / (2.0 * yinc)); MyVNorm(&normals[addr]); } } /* generate actual triangles */ for (y=0; y<(n-1); y++) { for (x=0; x<(m-1); x++) { addr = y*m + x; rt_stri(tex, vertices[addr], vertices[addr + 1 + m], vertices[addr + 1], normals[addr], normals[addr + 1 + m], normals[addr + 1]); rt_stri(tex, vertices[addr], vertices[addr + m], vertices[addr + 1 + m], normals[addr], normals[addr + m], normals[addr + 1 + m]); } } free(normals); free(vertices); } /* end of smoothed heightfield */