//Makes a mesh ball. #define VERTICES_NUM 1024 #define TRIS_NUM 1024 class Ball { I32 vertex_count; I32 tri_count; CD3I32 v[VERTICES_NUM]; CMeshTri t[TRIS_NUM]; } *b; class BallDefineStruct { F64 radius format "$DA-TRM,A=\"Radius :%8.3f\"$\n"; I64 n_longitude format "$DA-TRM,A=\"Longitude Faces:%5d\"$\n"; I64 n_lattitude format "$DA-TRM,A=\"Lattitude Rings:%5d\"$\n"; }; U0 BDInit(BallDefineStruct *bd) { MemSet(bd, 0, sizeof(BallDefineStruct)); bd->n_longitude = 16; bd->n_lattitude = 8; bd->radius = 20.0; } U0 BDCorrect(BallDefineStruct *bd) { bd->n_longitude = (bd->n_longitude + 1) / 2; bd->n_lattitude = (bd->n_lattitude + 1) / 2; } I64 AddVertex(BallDefineStruct *, I64 x, I64 y, I64 z) { I64 i; for (i = 0; i < b->vertex_count; i++) if (b->v[i].x == x && b->v[i].y == y && b->v[i].z == z) return i; i = b->vertex_count++; b->v[i].x = x; b->v[i].y = y; b->v[i].z = z; return i; } I64 AddTri(BallDefineStruct *, I64 c, I64 n0, I64 n1, I64 n2) { I64 res = b->tri_count++; b->t[res].color = c; b->t[res].nums[0] = n0; b->t[res].nums[1] = n1; b->t[res].nums[2] = n2; return res; } U8 *Ball2CSprite() { //See ::/System/Gr/GrSpritePlot.ZC for how CSprite are stored. U8 *res = MAlloc(sizeof(CSpriteMeshU8s) + b->vertex_count * sizeof(CD3I32) + b->tri_count * sizeof(CMeshTri) + sprite_elem_base_sizes[SPT_END]), *dst = res; *dst++ = SPT_MESH; *dst(I32 *)++ = b->vertex_count; *dst(I32 *)++ = b->tri_count; MemCopy(dst, &b->v, b->vertex_count * sizeof(CD3I32)); dst += b->vertex_count * sizeof(CD3I32); MemCopy(dst, &b->t, b->tri_count * sizeof(CMeshTri)); dst += b->tri_count * sizeof(CMeshTri); *dst++ = SPT_END; return res; } public U8 *BallGen() { U8 *res; I64 i, j, n, m, c, p1, p2, p3, p4; BallDefineStruct bd1, bd2; F64 r, r1, r2, z1, z2, d_a1, d_a2; BDInit(&bd1); while (TRUE) { if (!DocForm(&bd1)) return NULL; MemCopy(&bd2, &bd1, sizeof(BallDefineStruct)); BDCorrect(&bd2); c = PopUpColorLighting; if (c < 0) return NULL; b = CAlloc(sizeof(Ball)); r = bd2.radius; n = bd2.n_lattitude; m = bd2.n_longitude; d_a1 = 2 * pi / n / 4; d_a2 = 2 * pi / m / 2; for (j = -n; j < n; j++) { r1 = r * Cos( j *d_a1); r2 = r * Cos((j+1)*d_a1); z1 = r * Sin( j *d_a1); z2 = r * Sin((j+1)*d_a1); for (i = 0; i < m; i++) { p1 = AddVertex(&bd2, r1 * Cos((2 * i + j) * d_a2), r1 * Sin((2 * i + j) * d_a2), z1); p2 = AddVertex(&bd2, r1 * Cos((2 * i + 2 +j) * d_a2), r1 * Sin((2 * i + 2 + j) * d_a2), z1); p3 = AddVertex(&bd2, r2 * Cos((2 * i + 1 +j) * d_a2), r2 * Sin((2 * i + 1 + j) * d_a2), z2); p4 = AddVertex(&bd2, r2 * Cos((2 * i + 3 +j) * d_a2), r2 * Sin((2 * i + 3 + j) * d_a2), z2); AddTri(&bd2, c, p1, p2, p3); AddTri(&bd2, c, p3, p2, p4); } } res = Ball2CSprite; "%h7c", '\n'; Sprite(res, "\t\t$SP,\"<1>\",BI=%d$"); "%h7c", '\n'; "Vertices:%d\n", b->vertex_count; Free(b); "Do another"; if (YorN) Free(res); else break; } return res; }