/* rocks.c - Don Yang (uguu.org) 06/07/03 */ /*@ -realcompare @*/ #include"global.h" #include"rocks.h" #include"util.h" static GLuint ObjRockBase = 0, ObjOutlineBase = 0; static void BuildObjPart(double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double r, /*@out@*/double *x, /*@out@*/double *y, /*@out@*/double *z, int *i); static void DrawObj(double theta, double phi, double r, int index); /********************************************************* DrawRockOutline */ void DrawRockOutline(unsigned int type) { glCallList(ObjOutlineBase + (type & 31)); } /* DrawRockOutline() */ /************************************************************ DrawRockTile */ void DrawRockTile(unsigned int type) { glCallList(ObjRockBase + (type & 31)); } /* DrawRockTile() */ /*********************************************************** InitRockTiles */ void InitRockTiles(void) { double a1, a2; int i; ObjRockBase = glGenLists(32); ObjOutlineBase = glGenLists(32); for(i = 0; i < 32; i++) { a1 = Random(0.0, 2.0 * PI); a2 = Random(0.0, PI); DrawObj(a1, a2, 1.0 + (double)(i & 3), i); } } /* InitRockTiles() */ /********************************************************** SetupRockTiles */ void SetupRockTiles(void) { static const GLfloat rockambient[4] = {0.1f, 0.1f, 0.1f, 1.0f}; static const GLfloat rockdiffuse[4] = {0.6f, 0.6f, 0.6f, 1.0f}; static const GLfloat rockspecular[4] = {0.2f, 0.2f, 0.2f, 1.0f}; static const GLfloat rockemission[4] = {0.0f, 0.05f, 0.0f, 1.0f}; glShadeModel(GL_FLAT); glMaterialfv(GL_FRONT, GL_AMBIENT, rockambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, rockdiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, rockspecular); glMaterialfv(GL_FRONT, GL_EMISSION, rockemission); } /* SetupRockTiles() */ /********************************************************* UninitRockTiles */ void UninitRockTiles(void) { if( ObjRockBase != 0 ) glDeleteLists(ObjRockBase, 32); if( ObjOutlineBase != 0 ) glDeleteLists(ObjOutlineBase, 32); } /* UninitRockTiles() */ /************************************************************ BuildObjPart */ static void BuildObjPart(double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double r, /*@out@*/double *x, /*@out@*/double *y, /*@out@*/double *z, int *i) { double ax0, ay0, az0, bx0, by0, bz0, cx0, cy0, cz0; double nx, ny, nz; Cross(bx - ax, by - ay, bz - az, cx - ax, cy - ay, cz - az, &nx, &ny, &nz); Normalize(&nx, &ny, &nz, r); x[*i] = ax0 = ax + nx; y[*i] = ay0 = ay + ny; z[*i] = az0 = az + nz; ++*i; x[*i] = bx0 = bx + nx; y[*i] = by0 = by + ny; z[*i] = bz0 = bz + nz; ++*i; x[*i] = cx0 = cx + nx; y[*i] = cy0 = cy + ny; z[*i] = cz0 = cz + nz; ++*i; ax *= 1.4; bx *= 1.4; cx *= 1.4; ay *= 1.4; by *= 1.4; cy *= 1.4; az *= 1.4; bz *= 1.4; cz *= 1.4; x[*i] = ax; y[*i] = ay; z[*i] = az; ++*i; x[*i] = ax0; y[*i] = ay0; z[*i] = az0; ++*i; x[*i] = cx0; y[*i] = cy0; z[*i] = cz0; ++*i; x[*i] = cx0; y[*i] = cy0; z[*i] = cz0; ++*i; x[*i] = cx; y[*i] = cy; z[*i] = cz; ++*i; x[*i] = ax; y[*i] = ay; z[*i] = az; ++*i; x[*i] = bx; y[*i] = by; z[*i] = bz; ++*i; x[*i] = bx0; y[*i] = by0; z[*i] = bz0; ++*i; x[*i] = ax0; y[*i] = ay0; z[*i] = az0; ++*i; x[*i] = ax0; y[*i] = ay0; z[*i] = az0; ++*i; x[*i] = ax; y[*i] = ay; z[*i] = az; ++*i; x[*i] = bx; y[*i] = by; z[*i] = bz; ++*i; x[*i] = cx; y[*i] = cy; z[*i] = cz; ++*i; x[*i] = cx0; y[*i] = cy0; z[*i] = cz0; ++*i; x[*i] = bx0; y[*i] = by0; z[*i] = bz0; ++*i; x[*i] = bx0; y[*i] = by0; z[*i] = bz0; ++*i; x[*i] = bx; y[*i] = by; z[*i] = bz; ++*i; x[*i] = cx; y[*i] = cy; z[*i] = cz; ++*i; } /* BuildObjPart() */ /***************************************************************** DrawObj */ static void DrawObj(double theta, double phi, double r, int index) { static const double outlinescale = 1.1; double x[84], y[84], z[84]; double ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz; int i, polycount; /* Build object */ r *= 0.37; ax = bx = 0.0; ay = by = r; az = bz = 0.0; RotatePoint(0.0, PI * 2.0/3.0, &bx, &by, &bz); /* (util.c) */ cx = dx = bx; cy = dy = by; cz = dz = bz; RotatePoint(PI * 2.0/3.0, 0.0, &cx, &cy, &cz); RotatePoint(PI * 4.0/3.0, 0.0, &dx, &dy, &dz); RotatePoint(theta, phi, &ax, &ay, &az); RotatePoint(theta, phi, &bx, &by, &bz); RotatePoint(theta, phi, &cx, &cy, &cz); RotatePoint(theta, phi, &dx, &dy, &dz); polycount = 0; r *= 2.0; BuildObjPart(ax, ay, az, cx, cy, cz, bx, by, bz, r, x, y, z, &polycount); BuildObjPart(ax, ay, az, dx, dy, dz, cx, cy, cz, r, x, y, z, &polycount); BuildObjPart(ax, ay, az, bx, by, bz, dx, dy, dz, r, x, y, z, &polycount); BuildObjPart(bx, by, bz, cx, cy, cz, dx, dy, dz, r, x, y, z, &polycount); /* Align object with floor */ dy = 0.0; for(i = 0; i < polycount; i++) { if( y[i] < dy ) dy = y[i]; } /* Draw object */ glNewList(ObjRockBase + index, GL_COMPILE); glBegin(GL_TRIANGLES); for(i = 0; i < polycount; i++) { if( (i % 3) == 0 ) { ax = x[i]; bx = x[i + 1]; cx = x[i + 2]; ay = y[i]; by = y[i + 1]; cy = y[i + 2]; az = z[i]; bz = z[i + 1]; cz = z[i + 2]; glNormal3d((by - ay) * (cz - az) - (cy - ay) * (bz - az), (cx - ax) * (bz - az) - (bx - ax) * (cz - az), (bx - ax) * (cy - ay) - (cx - ax) * (by - ay)); } glVertex3d(x[i], y[i] - dy, z[i]); } glEnd(); glEndList(); /* Draw outline */ glNewList(ObjOutlineBase + index, GL_COMPILE); glBegin(GL_TRIANGLES); for(i = 0; i < polycount; i++) { if( (i % 3) == 0 ) { ax = x[i]; bx = x[i + 1]; cx = x[i + 2]; ay = y[i]; by = y[i + 1]; cy = y[i + 2]; az = z[i]; bz = z[i + 1]; cz = z[i + 2]; glNormal3d((by - ay) * (cz - az) - (cy - ay) * (bz - az), (cx - ax) * (bz - az) - (bx - ax) * (cz - az), (bx - ax) * (cy - ay) - (cx - ax) * (by - ay)); } glVertex3d(x[i] * outlinescale, y[i] * outlinescale - dy, z[i] * outlinescale); } glEnd(); glEndList(); } /* DrawObj() */