Thar0

Cylinder and Sphere drawing

May 30th, 2022
1,208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.24 KB | None | 0 0
  1. /*
  2.  *  Lazy port of a couple of functions from https://github.com/glankk/gz/blob/master/src/gz/gz_col_view.c to C89 + OoT Decomp
  3.  */
  4.  
  5. void Math3D_VtxF2L(Vtx* r, Vec3f* v) {
  6.     r->n.ob[0] = Math_FFloorF(0.5f + v->x * 128.0f);
  7.     r->n.ob[1] = Math_FFloorF(0.5f + v->y * 128.0f);
  8.     r->n.ob[2] = Math_FFloorF(0.5f + v->z * 128.0f);
  9.     r->n.flag = 0;
  10.     r->n.tc[0] = 0;
  11.     r->n.tc[1] = 0;
  12.     r->n.n[0] = v->x * 127.0f;
  13.     r->n.n[1] = v->y * 127.0f;
  14.     r->n.n[2] = v->z * 127.0f;
  15.     r->n.a = 0xFF;
  16. }
  17.  
  18. void Math3D_IcoSphSubdivideEdge(Vec3f* r, Vec3f* a, Vec3f* b) {
  19.     Math_Vec3f_Sum(a, b, r);
  20.     Math_Vec3f_Scale(r, 1.0f / Math3D_Vec3fMagnitude(r));
  21. }
  22.  
  23. static Gfx sPolyGfxInit[] = {
  24.     gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING),
  25.     gsSPTexture(0, 0, 0, G_TX_RENDERTILE, G_OFF),
  26.     gsDPPipeSync(),
  27.     gsDPSetCycleType(G_CYC_1CYCLE),
  28.     gsDPSetRenderMode(
  29.         Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA),
  30.         Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
  31.     gsDPSetCombineLERP(PRIMITIVE, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT, PRIMITIVE, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT),
  32.     gsDPSetEnvColor(255, 255, 255, 128),
  33.     gsSPEndDisplayList(),
  34. };
  35.  
  36. void Math3D_DrawSphereImpl(GraphicsContext* gfxCtx, Gfx** gfxP, f32 x, f32 y, f32 z, f32 radius) {
  37.     static Gfx* pSphGfx = NULL;
  38.     static Vtx sphVtx[42];
  39.     static Gfx sphGfx[45];
  40.  
  41.     Gfx* sphGfxP;
  42.     s32 i;
  43.  
  44.     if (!pSphGfx) {
  45.         Vec3f vtx[42];
  46.         s32 r0n = 1, r0m = r0n / 5, r0i = 0 + 0;
  47.         s32 r1n = 5, r1m = r1n / 5, r1i = r0i + r0n;
  48.         s32 r2n = 10, r2m = r2n / 5, r2i = r1i + r1n;
  49.         s32 r3n = 10, r3m = r3n / 5, r3i = r2i + r2n;
  50.         s32 r4n = 10, r4m = r4n / 5, r4i = r3i + r3n;
  51.         s32 r5n = 5, r5m = r5n / 5, r5i = r4i + r4n;
  52.         s32 r6n = 1, r6m = r6n / 5, r6i = r5i + r5n;
  53.  
  54.         vtx[r0i + (0 * r0m + 0) % r0n].x = 0.0f;
  55.         vtx[r0i + (0 * r0m + 0) % r0n].y = 1.0f;
  56.         vtx[r0i + (0 * r0m + 0) % r0n].z = 0.0f;
  57.  
  58.         vtx[r6i + (0 * r6m + 0) % r6n].x = 0.0f;
  59.         vtx[r6i + (0 * r6m + 0) % r6n].y = -1.0f;
  60.         vtx[r6i + (0 * r6m + 0) % r6n].z = 0.0f;
  61.  
  62.         for (i = 0; i < 5; ++i) {
  63.             static const f32 aXZ = 2.0f * M_PI / 10.0f;
  64.             static const f32 aY = 0.463647609f; // Math_FAtanF(1.0f / 2.0f);
  65.  
  66.             vtx[r2i + (i * r2m + 0) % r2n].x = cosf(aXZ * (i * r2m + 0)) * cosf(aY * 1.0f);
  67.             vtx[r2i + (i * r2m + 0) % r2n].y = sinf(aY * 1.0f);
  68.             vtx[r2i + (i * r2m + 0) % r2n].z = -sinf(aXZ * (i * r2m + 0)) * cosf(aY * 1.0f);
  69.  
  70.             vtx[r4i + (i * r4m + 0) % r4n].x = cosf(aXZ * (i * r4m + 1)) * cosf(aY * -1.0f);
  71.             vtx[r4i + (i * r4m + 0) % r4n].y = sinf(aY * -1.0f);
  72.             vtx[r4i + (i * r4m + 0) % r4n].z = -sinf(aXZ * (i * r4m + 1)) * cosf(aY * -1.0f);
  73.         }
  74.  
  75.         for (i = 0; i < 5; ++i) {
  76.             Math3D_IcoSphSubdivideEdge(&vtx[r1i + (i * r1m + 0) % r1n], &vtx[r0i + (i * r0m + 0) % r0n],
  77.                                        &vtx[r2i + (i * r2m + 0) % r2n]);
  78.             Math3D_IcoSphSubdivideEdge(&vtx[r2i + (i * r2m + 1) % r2n], &vtx[r2i + (i * r2m + 0) % r2n],
  79.                                        &vtx[r2i + (i * r2m + 2) % r2n]);
  80.             Math3D_IcoSphSubdivideEdge(&vtx[r3i + (i * r3m + 0) % r3n], &vtx[r2i + (i * r2m + 0) % r2n],
  81.                                        &vtx[r4i + (i * r4m + 0) % r4n]);
  82.             Math3D_IcoSphSubdivideEdge(&vtx[r3i + (i * r3m + 1) % r3n], &vtx[r4i + (i * r4m + 0) % r4n],
  83.                                        &vtx[r2i + (i * r2m + 2) % r2n]);
  84.             Math3D_IcoSphSubdivideEdge(&vtx[r4i + (i * r4m + 1) % r4n], &vtx[r4i + (i * r4m + 0) % r4n],
  85.                                        &vtx[r4i + (i * r4m + 2) % r4n]);
  86.             Math3D_IcoSphSubdivideEdge(&vtx[r5i + (i * r5m + 0) % r5n], &vtx[r4i + (i * r4m + 0) % r4n],
  87.                                        &vtx[r6i + (i * r6m + 0) % r6n]);
  88.         }
  89.  
  90.         for (i = 0; i < 42; ++i) {
  91.             Math3D_VtxF2L(&sphVtx[i], &vtx[i]);
  92.         }
  93.  
  94.         sphGfxP = pSphGfx = sphGfx;
  95.  
  96.         gSPSetGeometryMode(sphGfxP++, G_CULL_BACK | G_SHADING_SMOOTH);
  97.         gSPVertex(sphGfxP++, &sphVtx[r0i], r0n + r1n + r2n + r3n, r0i - r0i);
  98.  
  99.         r3i -= r0i;
  100.         r2i -= r0i;
  101.         r1i -= r0i;
  102.         r0i -= r0i;
  103.  
  104.         for (i = 0; i < 5; ++i) {
  105.             s32 v[24];
  106.  
  107.             v[0] = r0i + (i * r0m + 0) % r0n;
  108.             v[1] = r1i + (i * r1m + 0) % r1n;
  109.             v[2] = r1i + (i * r1m + 1) % r1n;
  110.             v[3] = r1i + (i * r1m + 0) % r1n;
  111.             v[4] = r2i + (i * r2m + 0) % r2n;
  112.             v[5] = r2i + (i * r2m + 1) % r2n;
  113.             v[6] = r1i + (i * r1m + 0) % r1n;
  114.             v[7] = r2i + (i * r2m + 1) % r2n;
  115.             v[8] = r1i + (i * r1m + 1) % r1n;
  116.             v[9] = r1i + (i * r1m + 1) % r1n;
  117.             v[10] = r2i + (i * r2m + 1) % r2n;
  118.             v[11] = r2i + (i * r2m + 2) % r2n;
  119.             v[12] = r2i + (i * r2m + 0) % r2n;
  120.             v[13] = r3i + (i * r3m + 0) % r3n;
  121.             v[14] = r2i + (i * r2m + 1) % r2n;
  122.             v[15] = r2i + (i * r2m + 1) % r2n;
  123.             v[16] = r3i + (i * r3m + 0) % r3n;
  124.             v[17] = r3i + (i * r3m + 1) % r3n;
  125.             v[18] = r2i + (i * r2m + 1) % r2n;
  126.             v[19] = r3i + (i * r3m + 1) % r3n;
  127.             v[20] = r2i + (i * r2m + 2) % r2n;
  128.             v[21] = r2i + (i * r2m + 2) % r2n;
  129.             v[22] = r3i + (i * r3m + 1) % r3n;
  130.             v[23] = r3i + (i * r3m + 2) % r3n;
  131.  
  132.             gSP2Triangles(sphGfxP++, v[0], v[1], v[2], 0, v[3], v[4], v[5], 0);
  133.             gSP2Triangles(sphGfxP++, v[6], v[7], v[8], 0, v[9], v[10], v[11], 0);
  134.             gSP2Triangles(sphGfxP++, v[12], v[13], v[14], 0, v[15], v[16], v[17], 0);
  135.             gSP2Triangles(sphGfxP++, v[18], v[19], v[20], 0, v[21], v[22], v[23], 0);
  136.         }
  137.  
  138.         gSPVertex(sphGfxP++, &sphVtx[r4i], r4n + r5n + r6n, r4i - r4i);
  139.  
  140.         r6i -= r4i;
  141.         r5i -= r4i;
  142.         r4i -= r4i;
  143.  
  144.         for (i = 0; i < 5; ++i) {
  145.             s32 v[24];
  146.  
  147.             v[0] = r3i + (i * r3m + 1) % r3n;
  148.             v[1] = r4i + (i * r4m + 0) % r4n;
  149.             v[2] = r4i + (i * r4m + 1) % r4n;
  150.             v[3] = r3i + (i * r3m + 1) % r3n;
  151.             v[4] = r4i + (i * r4m + 1) % r4n;
  152.             v[5] = r3i + (i * r3m + 2) % r3n;
  153.             v[6] = r3i + (i * r3m + 2) % r3n;
  154.             v[7] = r4i + (i * r4m + 1) % r4n;
  155.             v[8] = r4i + (i * r4m + 2) % r4n;
  156.             v[9] = r3i + (i * r3m + 2) % r3n;
  157.             v[10] = r4i + (i * r4m + 2) % r4n;
  158.             v[11] = r3i + (i * r3m + 3) % r3n;
  159.             v[12] = r4i + (i * r4m + 0) % r4n;
  160.             v[13] = r5i + (i * r5m + 0) % r5n;
  161.             v[14] = r4i + (i * r4m + 1) % r4n;
  162.             v[15] = r4i + (i * r4m + 1) % r4n;
  163.             v[16] = r5i + (i * r5m + 0) % r5n;
  164.             v[17] = r5i + (i * r5m + 1) % r5n;
  165.             v[18] = r4i + (i * r4m + 1) % r4n;
  166.             v[19] = r5i + (i * r5m + 1) % r5n;
  167.             v[20] = r4i + (i * r4m + 2) % r4n;
  168.             v[21] = r5i + (i * r5m + 0) % r5n;
  169.             v[22] = r6i + (i * r6m + 0) % r6n;
  170.             v[23] = r5i + (i * r5m + 1) % r5n;
  171.  
  172.             gSP2Triangles(sphGfxP++, v[0], v[1], v[2], 0, v[3], v[4], v[5], 0);
  173.             gSP2Triangles(sphGfxP++, v[6], v[7], v[8], 0, v[9], v[10], v[11], 0);
  174.             gSP2Triangles(sphGfxP++, v[12], v[13], v[14], 0, v[15], v[16], v[17], 0);
  175.             gSP2Triangles(sphGfxP++, v[18], v[19], v[20], 0, v[21], v[22], v[23], 0);
  176.         }
  177.         gSPClearGeometryMode(sphGfxP++, G_CULL_BACK | G_SHADING_SMOOTH);
  178.         gSPEndDisplayList(sphGfxP++);
  179.     }
  180.  
  181.     Matrix_Push();
  182.  
  183.     Matrix_Translate(x, y, z, MTXMODE_NEW);
  184.     Matrix_Scale(radius / 128.0f, radius / 128.0f, radius / 128.0f, MTXMODE_APPLY);
  185.  
  186.     gSPMatrix((*gfxP)++, Matrix_NewMtx(gfxCtx, __FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH);
  187.     gSPDisplayList((*gfxP)++, pSphGfx);
  188.     gSPPopMatrix((*gfxP)++, G_MTX_MODELVIEW);
  189.  
  190.     Matrix_Pop();
  191. }
  192.  
  193. void Math3D_DrawSphere(PlayState* play, Sphere16* sph) {
  194.     OPEN_DISPS(play->state.gfxCtx, __FILE__, __LINE__);
  195.  
  196.     gSPDisplayList(POLY_XLU_DISP++, sPolyGfxInit);
  197.     gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255);
  198.  
  199.     Math3D_DrawSphereImpl(play->state.gfxCtx, &POLY_XLU_DISP, sph->center.x, sph->center.y, sph->center.z, sph->radius);
  200.  
  201.     CLOSE_DISPS(play->state.gfxCtx, __FILE__, __LINE__);
  202. }
  203.  
  204. void Math3D_DrawCylinderImpl(GraphicsContext* gfxCtx, Gfx** gfxP, f32 x, f32 y, f32 z, s16 radius, s16 height) {
  205.     static Gfx* pCylGfx = NULL;
  206.  
  207.     if (!pCylGfx) {
  208.         static Gfx cylGfx[5 + 12 * 2];
  209.         static Vtx cylVtx[2 + 12 * 2];
  210.  
  211.         s32 i;
  212.         Gfx* cylGfxP = pCylGfx = cylGfx;
  213.  
  214.         cylVtx[0].n.ob[0] = 0;
  215.         cylVtx[0].n.ob[1] = 0;
  216.         cylVtx[0].n.ob[2] = 0;
  217.         cylVtx[0].n.flag = 0;
  218.         cylVtx[0].n.tc[0] = 0;
  219.         cylVtx[0].n.tc[1] = 0;
  220.         cylVtx[0].n.n[0] = 0;
  221.         cylVtx[0].n.n[1] = -127;
  222.         cylVtx[0].n.n[2] = 0;
  223.         cylVtx[0].n.a = 255;
  224.  
  225.         cylVtx[1].n.ob[0] = 0;
  226.         cylVtx[1].n.ob[1] = 128;
  227.         cylVtx[1].n.ob[2] = 0;
  228.         cylVtx[1].n.flag = 0;
  229.         cylVtx[1].n.tc[0] = 0;
  230.         cylVtx[1].n.tc[1] = 0;
  231.         cylVtx[1].n.n[0] = 0;
  232.         cylVtx[1].n.n[1] = 127;
  233.         cylVtx[1].n.n[2] = 0;
  234.         cylVtx[1].n.a = 255;
  235.  
  236.         for (i = 0; i < 12; ++i) {
  237.             s32 vtxX = Math_FFloorF(0.5f + cosf(2.f * M_PI * i / 12) * 128.f);
  238.             s32 vtxZ = Math_FFloorF(0.5f - sinf(2.f * M_PI * i / 12) * 128.f);
  239.             s32 normX = cosf(2.f * M_PI * i / 12) * 127.f;
  240.             s32 normZ = -sinf(2.f * M_PI * i / 12) * 127.f;
  241.  
  242.             cylVtx[2 + i * 2 + 0].n.ob[0] = vtxX;
  243.             cylVtx[2 + i * 2 + 0].n.ob[1] = 0;
  244.             cylVtx[2 + i * 2 + 0].n.ob[2] = vtxZ;
  245.             cylVtx[2 + i * 2 + 0].n.flag = 0;
  246.             cylVtx[2 + i * 2 + 0].n.tc[0] = 0;
  247.             cylVtx[2 + i * 2 + 0].n.tc[1] = 0;
  248.             cylVtx[2 + i * 2 + 0].n.n[0] = normX;
  249.             cylVtx[2 + i * 2 + 0].n.n[1] = 0;
  250.             cylVtx[2 + i * 2 + 0].n.n[2] = normZ;
  251.             cylVtx[2 + i * 2 + 0].n.a = 255;
  252.  
  253.             cylVtx[2 + i * 2 + 1].n.ob[0] = vtxX;
  254.             cylVtx[2 + i * 2 + 1].n.ob[1] = 128;
  255.             cylVtx[2 + i * 2 + 1].n.ob[2] = vtxZ;
  256.             cylVtx[2 + i * 2 + 1].n.flag = 0;
  257.             cylVtx[2 + i * 2 + 1].n.tc[0] = 0;
  258.             cylVtx[2 + i * 2 + 1].n.tc[1] = 0;
  259.             cylVtx[2 + i * 2 + 1].n.n[0] = normX;
  260.             cylVtx[2 + i * 2 + 1].n.n[1] = 0;
  261.             cylVtx[2 + i * 2 + 1].n.n[2] = normZ;
  262.             cylVtx[2 + i * 2 + 1].n.a = 255;
  263.         }
  264.  
  265.         gSPSetGeometryMode(cylGfxP++, G_CULL_BACK | G_SHADING_SMOOTH);
  266.         gSPVertex(cylGfxP++, cylVtx, 2 + 12 * 2, 0);
  267.  
  268.         for (i = 0; i < 12; ++i) {
  269.             s32 p = (i + 12 - 1) % 12;
  270.  
  271.             gSP2Triangles(cylGfxP++, 2 + p * 2 + 0, 2 + i * 2 + 0, 2 + i * 2 + 1, 0, 2 + p * 2 + 0, 2 + i * 2 + 1,
  272.                           2 + p * 2 + 1, 0);
  273.         }
  274.  
  275.         gSPClearGeometryMode(cylGfxP++, G_SHADING_SMOOTH);
  276.  
  277.         for (i = 0; i < 12; ++i) {
  278.             s32 p = (i + 12 - 1) % 12;
  279.  
  280.             gSP2Triangles(cylGfxP++, 0, 2 + i * 2 + 0, 2 + p * 2 + 0, 0, 1, 2 + p * 2 + 1, 2 + i * 2 + 1, 0);
  281.         }
  282.  
  283.         gSPClearGeometryMode(cylGfxP++, G_CULL_BACK);
  284.         gSPEndDisplayList(cylGfxP++);
  285.     }
  286.  
  287.     Matrix_Push();
  288.  
  289.     Matrix_Translate(x, y, z, MTXMODE_NEW);
  290.     Matrix_Scale(radius / 128.0f, height / 128.0f, radius / 128.0f, MTXMODE_APPLY);
  291.  
  292.     gSPMatrix((*gfxP)++, Matrix_NewMtx(gfxCtx, __FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH);
  293.     gSPDisplayList((*gfxP)++, pCylGfx);
  294.     gSPPopMatrix((*gfxP)++, G_MTX_MODELVIEW);
  295.  
  296.     Matrix_Pop();
  297. }
  298.  
  299. void Math3D_DrawCylinder(PlayState* play, Cylinder16* cyl) {
  300.     OPEN_DISPS(play->state.gfxCtx, __FILE__, __LINE__);
  301.  
  302.     gSPDisplayList(POLY_XLU_DISP++, sPolyGfxInit);
  303.     gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255);
  304.  
  305.     Math3D_DrawCylinderImpl(play->state.gfxCtx, &POLY_XLU_DISP, cyl->pos.x, cyl->pos.y + cyl->yShift, cyl->pos.z,
  306.                             cyl->radius, cyl->height);
  307.  
  308.     CLOSE_DISPS(play->state.gfxCtx, __FILE__, __LINE__);
  309. }
  310.  
Advertisement
Add Comment
Please, Sign In to add comment