X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fmesh.c;fp=src%2Fmesh.c;h=0000000000000000000000000000000000000000;hp=0e8d869312be48dd74ef09c03d8bdd24b557fb63;hb=57bd2dc519c47f434e3e5acf998fb9c72448cbce;hpb=d956a9d9273eebfacfda58cb3bafff017269d5dc diff --git a/src/mesh.c b/src/mesh.c deleted file mode 100644 index 0e8d869..0000000 --- a/src/mesh.c +++ /dev/null @@ -1,524 +0,0 @@ -#include -#include -#include -#include -#include "mesh.h" -#include "3dgfx.h" - -void free_mesh(struct g3d_mesh *mesh) -{ - destroy_mesh(mesh); - free(mesh); -} - -void destroy_mesh(struct g3d_mesh *mesh) -{ - free(mesh->varr); - free(mesh->iarr); -} - -int copy_mesh(struct g3d_mesh *dest, struct g3d_mesh *src) -{ - dest->prim = src->prim; - if(src->varr) { - if(!(dest->varr = malloc(src->vcount * sizeof *src->varr))) { - return -1; - } - memcpy(dest->varr, src->varr, src->vcount * sizeof *src->varr); - } - dest->vcount = src->vcount; - if(src->iarr) { - if(!(dest->iarr = malloc(src->icount * sizeof *src->iarr))) { - free(dest->varr); - dest->varr = 0; - return -1; - } - memcpy(dest->iarr, src->iarr, src->icount * sizeof *src->iarr); - } - dest->icount = src->icount; - return 0; -} - -static struct { - int prim; - struct g3d_vertex *varr; - const float *xform; -} zsort_cls; - -static int zsort_cmp(const void *aptr, const void *bptr) -{ - int i; - float za = 0.0f; - float zb = 0.0f; - const float *m = zsort_cls.xform; - const struct g3d_vertex *va = (const struct g3d_vertex*)aptr; - const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr; - - for(i=0; ix + m[6] * va->y + m[10] * va->z + m[14]; - zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - ++va; - ++vb; - } - return za - zb; -} - -static int zsort_indexed_cmp(const void *aptr, const void *bptr) -{ - int i; - float za = 0.0f; - float zb = 0.0f; - const uint16_t *a = (const uint16_t*)aptr; - const uint16_t *b = (const uint16_t*)bptr; - - const float *m = zsort_cls.xform; - - for(i=0; ix + m[6] * va->y + m[10] * va->z + m[14]; - zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - } - return za - zb; -} - - -void zsort_mesh(struct g3d_mesh *m) -{ - zsort_cls.varr = m->varr; - zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0); - zsort_cls.prim = m->prim; - - if(m->iarr) { - int nfaces = m->icount / m->prim; - qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_indexed_cmp); - } else { - int nfaces = m->vcount / m->prim; - qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp); - } -} - - -void draw_mesh(struct g3d_mesh *mesh) -{ - if(mesh->iarr) { - g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount); - } else { - g3d_draw(mesh->prim, mesh->varr, mesh->vcount); - } -} - -void apply_mesh_xform(struct g3d_mesh *mesh, const float *xform) -{ - int i; - struct g3d_vertex *v = mesh->varr; - - for(i=0; ivcount; i++) { - float x = xform[0] * v->x + xform[4] * v->y + xform[8] * v->z + xform[12]; - float y = xform[1] * v->x + xform[5] * v->y + xform[9] * v->z + xform[13]; - v->z = xform[2] * v->x + xform[6] * v->y + xform[10] * v->z + xform[14]; - v->x = x; - v->y = y; - x = xform[0] * v->nx + xform[4] * v->ny + xform[8] * v->nz; - y = xform[1] * v->nx + xform[5] * v->ny + xform[9] * v->nz; - v->nz = xform[2] * v->nx + xform[6] * v->ny + xform[10] * v->nz; - v->nx = x; - v->ny = y; - ++v; - } -} - -int append_mesh(struct g3d_mesh *ma, struct g3d_mesh *mb) -{ - int i, new_vcount, new_icount; - void *tmp; - uint16_t *iptr; - - if(ma->prim != mb->prim) { - fprintf(stderr, "append_mesh failed, primitive mismatch\n"); - return -1; - } - - if(ma->iarr || mb->iarr) { - if(!ma->iarr) { - if(indexify_mesh(ma) == -1) { - return -1; - } - } else if(!mb->iarr) { - if(indexify_mesh(mb) == -1) { - return -1; - } - } - - new_icount = ma->icount + mb->icount; - if(!(iptr = realloc(ma->iarr, new_icount * sizeof *iptr))) { - fprintf(stderr, "append_mesh: failed to allocate combined index buffer (%d indices)\n", new_icount); - return -1; - } - ma->iarr = iptr; - - iptr += ma->icount; - for(i=0; iicount; i++) { - *iptr++ = mb->iarr[i] + ma->vcount; - } - ma->icount = new_icount; - } - - new_vcount = ma->vcount + mb->vcount; - if(!(tmp = realloc(ma->varr, new_vcount * sizeof *ma->varr))) { - fprintf(stderr, "append_mesh: failed to allocate combined vertex buffer (%d verts)\n", new_vcount); - return -1; - } - ma->varr = tmp; - memcpy(ma->varr + ma->vcount, mb->varr, mb->vcount * sizeof *ma->varr); - ma->vcount = new_vcount; - return 0; -} - -#define FEQ(a, b) ((a) - (b) < 1e-5 && (b) - (a) < 1e-5) -static int cmp_vertex(struct g3d_vertex *a, struct g3d_vertex *b) -{ - if(!FEQ(a->x, b->x) || !FEQ(a->y, b->y) || !FEQ(a->z, b->z) || !FEQ(a->w, b->w)) - return -1; - if(!FEQ(a->nx, b->nx) || !FEQ(a->ny, b->ny) || !FEQ(a->nz, b->nz)) - return -1; - if(!FEQ(a->u, b->u) || !FEQ(a->v, b->v)) - return -1; - if(a->r != b->r || a->g != b->g || a->b != b->b || a->a != b->a) - return -1; - return 0; -} - -static int find_existing(struct g3d_vertex *v, struct g3d_vertex *varr, int vcount) -{ - int i; - for(i=0; iiarr) { - fprintf(stderr, "indexify_mesh failed: already indexed\n"); - return -1; - } - - nfaces = mesh->vcount / mesh->prim; - max_icount = mesh->vcount; - - if(!(mesh->iarr = malloc(max_icount * sizeof *mesh->iarr))) { - fprintf(stderr, "indexify_mesh failed to allocate index buffer of %d indices\n", max_icount); - return -1; - } - - vin = vout = mesh->varr; - iout = mesh->iarr; - - for(i=0; iprim; j++) { - if((idx = find_existing(vin, mesh->varr, out_vcount)) >= 0) { - *iout++ = idx; - } else { - *iout++ = out_vcount++; - if(vin != vout) { - *vout++ = *vin; - } - } - ++vin; - } - } - - /* XXX also shrink buffers? I'll just leave them to max size for now */ - return 0; -} - -void normalize_mesh_normals(struct g3d_mesh *mesh) -{ - int i; - struct g3d_vertex *v = mesh->varr; - - for(i=0; ivcount; i++) { - float mag = sqrt(v->nx * v->nx + v->ny * v->ny + v->nz * v->nz); - float s = (mag == 0.0f) ? 1.0f : 1.0f / mag; - v->nx *= s; - v->ny *= s; - v->nz *= s; - ++v; - } -} - - -static void sphvec(float *res, float theta, float phi, float rad) -{ - theta = -theta; - res[0] = sin(theta) * sin(phi); - res[1] = cos(phi); - res[2] = cos(theta) * sin(phi); -} - -int gen_sphere_mesh(struct g3d_mesh *mesh, float rad, int usub, int vsub) -{ - int i, j; - int nfaces, uverts, vverts; - struct g3d_vertex *vptr; - uint16_t *iptr; - - mesh->prim = G3D_QUADS; - - if(usub < 4) usub = 4; - if(vsub < 2) vsub = 2; - - uverts = usub + 1; - vverts = vsub + 1; - - mesh->vcount = uverts * vverts; - nfaces = usub * vsub; - mesh->icount = nfaces * 4; - - if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) { - fprintf(stderr, "gen_sphere_mesh: failed to allocate vertex buffer (%d vertices)\n", mesh->vcount); - return -1; - } - if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) { - fprintf(stderr, "gen_sphere_mesh: failed to allocate index buffer (%d indices)\n", mesh->icount); - return -1; - } - vptr = mesh->varr; - iptr = mesh->iarr; - - for(i=0; ix, theta, phi, rad); - vptr->w = 1.0f; - - vptr->nx = vptr->x / rad; - vptr->ny = vptr->y / rad; - vptr->nz = vptr->z / rad; - vptr->u = u; - vptr->v = v; - vptr->r = chess ? 255 : 64; - vptr->g = 128; - vptr->b = chess ? 64 : 255; - ++vptr; - - if(i < usub && j < vsub) { - int idx = i * vverts + j; - *iptr++ = idx; - *iptr++ = idx + 1; - *iptr++ = idx + vverts + 1; - *iptr++ = idx + vverts; - } - } - } - return 0; -} - -int gen_plane_mesh(struct g3d_mesh *m, float width, float height, int usub, int vsub) -{ - int i, j; - int nfaces, nverts, nidx, uverts, vverts; - float x, y, u, v, du, dv; - struct g3d_vertex *vptr; - uint16_t *iptr; - - if(usub < 1) usub = 1; - if(vsub < 1) vsub = 1; - - nfaces = usub * vsub; - uverts = usub + 1; - vverts = vsub + 1; - du = (float)width / (float)usub; - dv = (float)height / (float)vsub; - - nverts = uverts * vverts; - nidx = nfaces * 4; - - if(!(m->varr = malloc(nverts * sizeof *m->varr))) { - fprintf(stderr, "gen_plane_mesh: failed to allocate vertex buffer (%d vertices)\n", nverts); - return -1; - } - if(!(m->iarr = malloc(nidx * sizeof *m->iarr))) { - fprintf(stderr, "gen_plane_mesh: failed to allocate index buffer (%d indices)\n", nidx); - free(m->varr); - m->varr = 0; - return -1; - } - - m->prim = G3D_QUADS; - m->vcount = nverts; - m->icount = nidx; - - vptr = m->varr; - iptr = m->iarr; - - v = 0.0f; - for(i=0; ix = x; - vptr->y = y; - vptr->z = 0.0f; - vptr->w = 1.0f; - vptr->nx = 0.0f; - vptr->ny = 0.0f; - vptr->nz = 1.0f; - vptr->u = u; - vptr->v = v; - vptr->r = vptr->g = vptr->b = vptr->a = 255; - ++vptr; - - u += du; - } - v += dv; - } - - for(i=0; i 0 ? &tmpmesh : mesh; - if(gen_plane_mesh(m, sz, sz, sub, sub) == -1) - return -1; - g3d_load_identity(); - g3d_rotate(rotface[i][0], rotface[i][1], rotface[i][2], rotface[i][3]); - g3d_translate(0, 0, sz / 2.0f); - apply_mesh_xform(m, g3d_get_matrix(G3D_MODELVIEW, 0)); - if(i > 0) { - if(append_mesh(mesh, m) == -1) { - return -1; - } - } - } - - g3d_pop_matrix(); - return 0; -} - -static void torusvec(float *res, float theta, float phi, float mr, float rr) -{ - float rx, ry, rz; - theta = -theta; - - rx = -cos(phi) * rr + mr; - ry = sin(phi) * rr; - rz = 0.0f; - - res[0] = rx * sin(theta) + rz * cos(theta); - res[1] = ry; - res[2] = -rx * cos(theta) + rz * sin(theta); -} - -int gen_torus_mesh(struct g3d_mesh *mesh, float rad, float ringrad, int usub, int vsub) -{ - int i, j; - int nfaces, uverts, vverts; - struct g3d_vertex *vptr; - uint16_t *iptr; - - mesh->prim = G3D_QUADS; - - if(usub < 4) usub = 4; - if(vsub < 2) vsub = 2; - - uverts = usub + 1; - vverts = vsub + 1; - - mesh->vcount = uverts * vverts; - nfaces = usub * vsub; - mesh->icount = nfaces * 4; - - printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount); - - if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) { - return -1; - } - if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) { - return -1; - } - vptr = mesh->varr; - iptr = mesh->iarr; - - for(i=0; ix, theta, phi, rad, ringrad); - vptr->w = 1.0f; - - vptr->nx = (vptr->x - rcent[0]) / ringrad; - vptr->ny = (vptr->y - rcent[1]) / ringrad; - vptr->nz = (vptr->z - rcent[2]) / ringrad; - vptr->u = u; - vptr->v = v; - vptr->r = chess ? 255 : 64; - vptr->g = 128; - vptr->b = chess ? 64 : 255; - ++vptr; - - if(i < usub && j < vsub) { - int idx = i * vverts + j; - *iptr++ = idx; - *iptr++ = idx + 1; - *iptr++ = idx + vverts + 1; - *iptr++ = idx + vverts; - } - } - } - return 0; -} -