--- ray/src/common/mesh.c 2003/11/14 17:22:06 2.15 +++ ray/src/common/mesh.c 2012/11/06 17:12:35 2.26 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: mesh.c,v 2.15 2003/11/14 17:22:06 schorsch Exp $"; +static const char RCSid[] = "$Id: mesh.c,v 2.26 2012/11/06 17:12:35 greg Exp $"; #endif /* * Mesh support routines @@ -10,7 +10,7 @@ static const char RCSid[] = "$Id: mesh.c,v 2.15 2003/1 #include "rtio.h" #include "rtmath.h" #include "rterror.h" - +#include "paths.h" #include "octree.h" #include "object.h" #include "otypes.h" @@ -21,7 +21,7 @@ typedef struct { int fl; uint32 xyz[3]; int32 norm; - uint16 uv[2]; + uint32 uv[2]; } MCVERT; #define MPATCHBLKSIZ 128 /* patch allocation block size */ @@ -32,9 +32,9 @@ static MESH *mlist = NULL; /* list of loaded meshes * static unsigned long -cvhash(cvp) /* hash an encoded vertex */ -MCVERT *cvp; +cvhash(const char *p) /* hash an encoded vertex */ { + const MCVERT *cvp = (const MCVERT *)p; unsigned long hval; if (!(cvp->fl & MT_V)) @@ -49,9 +49,9 @@ MCVERT *cvp; static int -cvcmp(v1, v2) /* compare encoded vertices */ -register MCVERT *v1, *v2; +cvcmp(const char *vv1, const char *vv2) /* compare encoded vertices */ { + const MCVERT *v1 = (const MCVERT *)vv1, *v2 = (const MCVERT *)vv2; if (v1->fl != v2->fl) return(1); if (v1->xyz[0] != v2->xyz[0]) @@ -73,12 +73,13 @@ register MCVERT *v1, *v2; MESH * -getmesh(mname, flags) /* get new mesh data reference */ -char *mname; -int flags; +getmesh( /* get new mesh data reference */ + char *mname, + int flags +) { char *pathname; - register MESH *ms; + MESH *ms; flags &= IO_LEGAL; for (ms = mlist; ms != NULL; ms = ms->next) @@ -108,11 +109,12 @@ int flags; MESHINST * -getmeshinst(o, flags) /* create mesh instance */ -OBJREC *o; -int flags; +getmeshinst( /* create mesh instance */ + OBJREC *o, + int flags +) { - register MESHINST *ins; + MESHINST *ins; flags &= IO_LEGAL; if ((ins = (MESHINST *)o->os) == NULL) { @@ -141,12 +143,44 @@ int flags; int -getmeshtrivid(tvid, mo, mp, ti) /* get triangle vertex ID's */ -int32 tvid[3]; -OBJECT *mo; -MESH *mp; -OBJECT ti; +nextmeshtri( /* get next triangle ID */ + OBJECT *tip, + MESH *mp +) { + int pn; + MESHPATCH *pp; + + pn = ++(*tip) >> 10; /* next triangle (OVOID init) */ + while (pn < mp->npatches) { + pp = &mp->patch[pn]; + if (!(*tip & 0x200)) { /* local triangle? */ + if ((*tip & 0x1ff) < pp->ntris) + return(1); + *tip &= ~0x1ff; /* move on to single-joiners */ + *tip |= 0x200; + } + if (!(*tip & 0x100)) { /* single joiner? */ + if ((*tip & 0xff) < pp->nj1tris) + return(1); + *tip &= ~0xff; /* move on to double-joiners */ + *tip |= 0x100; + } + if ((*tip & 0xff) < pp->nj2tris) + return(1); + *tip = ++pn << 10; /* first in next patch */ + } + return(0); /* out of patches */ +} + +int +getmeshtrivid( /* get triangle vertex ID's */ + int32 tvid[3], + OBJECT *mo, + MESH *mp, + OBJECT ti +) +{ int pn = ti >> 10; MESHPATCH *pp; @@ -202,16 +236,17 @@ OBJECT ti; int -getmeshvert(vp, mp, vid, what) /* get triangle vertex from ID */ -MESHVERT *vp; -MESH *mp; -int32 vid; -int what; +getmeshvert( /* get triangle vertex from ID */ + MESHVERT *vp, + MESH *mp, + int32 vid, + int what +) { int pn = vid >> 8; MESHPATCH *pp; double vres; - register int i; + int i; vp->fl = 0; if (pn >= mp->npatches) @@ -238,7 +273,7 @@ int what; for (i = 0; i < 2; i++) vp->uv[i] = mp->uvlim[0][i] + (mp->uvlim[1][i] - mp->uvlim[0][i])* - (pp->uv[vid][i] + .5)*(1./65536.); + (pp->uv[vid][i] + .5)*(1./4294967296.); vp->fl |= MT_UV; } return(vp->fl); @@ -246,14 +281,15 @@ int what; OBJREC * -getmeshpseudo(mp, mo) /* get mesh pseudo object for material */ -MESH *mp; -OBJECT mo; +getmeshpseudo( /* get mesh pseudo object for material */ + MESH *mp, + OBJECT mo +) { if (mo < mp->mat0 || mo >= mp->mat0 + mp->nmats) error(INTERNAL, "modifier out of range in getmeshpseudo"); if (mp->pseudo == NULL) { - register int i; + int i; mp->pseudo = (OBJREC *)calloc(mp->nmats, sizeof(OBJREC)); if (mp->pseudo == NULL) error(SYSTEM, "out of memory in getmeshpseudo"); @@ -268,12 +304,13 @@ OBJECT mo; int -getmeshtri(tv, mo, mp, ti, wha) /* get triangle vertices */ -MESHVERT tv[3]; -OBJECT *mo; -MESH *mp; -OBJECT ti; -int wha; +getmeshtri( /* get triangle vertices */ + MESHVERT tv[3], + OBJECT *mo, + MESH *mp, + OBJECT ti, + int wha +) { int32 tvid[3]; @@ -289,13 +326,14 @@ int wha; int32 -addmeshvert(mp, vp) /* find/add a mesh vertex */ -register MESH *mp; -MESHVERT *vp; +addmeshvert( /* find/add a mesh vertex */ + MESH *mp, + MESHVERT *vp +) { LUENT *lvp; MCVERT cv; - register int i; + int i; if (!(vp->fl & MT_V)) return(-1); @@ -309,7 +347,7 @@ MESHVERT *vp; (vp->v[i] - mp->mcube.cuorg[i]) / mp->mcube.cusize); } - if (vp->fl & MT_N) + if (vp->fl & MT_N) /* assumes normalized! */ cv.norm = encodedir(vp->n); if (vp->fl & MT_UV) for (i = 0; i < 2; i++) { @@ -317,7 +355,7 @@ MESHVERT *vp; return(-1); if (vp->uv[i] >= mp->uvlim[1][i]) return(-1); - cv.uv[i] = (uint32)(65536. * + cv.uv[i] = (uint32)(4294967296. * (vp->uv[i] - mp->uvlim[0][i]) / (mp->uvlim[1][i] - mp->uvlim[0][i])); } @@ -338,7 +376,7 @@ MESHVERT *vp; memcpy((void *)lvp->key, (void *)&cv, sizeof(MCVERT)); } if (lvp->data == NULL) { /* new vertex */ - register MESHPATCH *pp; + MESHPATCH *pp; if (mp->npatches <= 0) { mp->patch = (MESHPATCH *)calloc(MPATCHBLKSIZ, sizeof(MESHPATCH)); @@ -375,8 +413,8 @@ MESHVERT *vp; } if (cv.fl & MT_UV) { if (pp->uv == NULL) { - pp->uv = (uint16 (*)[2])calloc(256, - 2*sizeof(uint16)); + pp->uv = (uint32 (*)[2])calloc(256, + 2*sizeof(uint32)); if (pp->uv == NULL) goto nomem; } @@ -395,14 +433,15 @@ nomem: OBJECT -addmeshtri(mp, tv, mo) /* add a new mesh triangle */ -MESH *mp; -MESHVERT tv[3]; -OBJECT mo; +addmeshtri( /* add a new mesh triangle */ + MESH *mp, + MESHVERT tv[3], + OBJECT mo +) { int32 vid[3], t; int pn[3], i; - register MESHPATCH *pp; + MESHPATCH *pp; if (!(tv[0].fl & tv[1].fl & tv[2].fl & MT_V)) return(OVOID); @@ -492,12 +531,11 @@ nomem: char * -checkmesh(mp) /* validate mesh data */ -register MESH *mp; +checkmesh(MESH *mp) /* validate mesh data */ { static char embuf[128]; int nouvbounds = 1; - register int i; + int i; /* basic checks */ if (mp == NULL) return("NULL mesh pointer"); @@ -537,7 +575,7 @@ register MESH *mp; if (mp->npatches <= 0) error(WARNING, "no patches in mesh"); for (i = 0; i < mp->npatches; i++) { - register MESHPATCH *pp = &mp->patch[i]; + MESHPATCH *pp = &mp->patch[i]; if (pp->nverts <= 0) error(WARNING, "no vertices in patch"); else { @@ -546,8 +584,6 @@ register MESH *mp; if (nouvbounds && pp->uv != NULL) return("unreferenced uv coordinates"); } - if (pp->ntris + pp->nj1tris + pp->nj2tris <= 0) - error(WARNING, "no triangles in patch"); if (pp->ntris > 0 && pp->tri == NULL) return("missing patch triangle list"); if (pp->nj1tris > 0 && pp->j1tri == NULL) @@ -561,9 +597,12 @@ register MESH *mp; static void -tallyoctree(ot, ecp, lcp, ocp) /* tally octree size */ -OCTREE ot; -int *ecp, *lcp, *ocp; +tallyoctree( /* tally octree size */ + OCTREE ot, + int *ecp, + int *lcp, + int *ocp +) { int i; @@ -584,9 +623,10 @@ int *ecp, *lcp, *ocp; void -printmeshstats(ms, fp) /* print out mesh statistics */ -MESH *ms; -FILE *fp; +printmeshstats( /* print out mesh statistics */ + MESH *ms, + FILE *fp +) { int lfcnt=0, lecnt=0, locnt=0; int vcnt=0, ncnt=0, uvcnt=0; @@ -596,7 +636,7 @@ FILE *fp; tallyoctree(ms->mcube.cutree, &lecnt, &lfcnt, &locnt); for (i = 0; i < ms->npatches; i++) { - register MESHPATCH *pp = &ms->patch[i]; + MESHPATCH *pp = &ms->patch[i]; vcnt += pp->nverts; if (pp->norm != NULL) { for (j = pp->nverts; j--; ) @@ -615,12 +655,12 @@ FILE *fp; t2cnt += pp->nj2tris; } fprintf(fp, "Mesh statistics:\n"); - fprintf(fp, "\t%ld materials\n", ms->nmats); + fprintf(fp, "\t%ld materials\n", (long)ms->nmats); fprintf(fp, "\t%d patches (%.2f MBytes)\n", ms->npatches, (ms->npatches*sizeof(MESHPATCH) + vcnt*3*sizeof(uint32) + nscnt*sizeof(int32) + - uvscnt*2*sizeof(uint16) + + uvscnt*2*sizeof(uint32) + tcnt*sizeof(struct PTri) + t1cnt*sizeof(struct PJoin1) + t2cnt*sizeof(struct PJoin2))/(1024.*1024.)); @@ -638,8 +678,7 @@ FILE *fp; void -freemesh(ms) /* free mesh data */ -register MESH *ms; +freemesh(MESH *ms) /* free mesh data */ { MESH mhead; MESH *msp; @@ -667,7 +706,7 @@ register MESH *ms; octfree(ms->mcube.cutree); lu_done(&ms->lut); if (ms->npatches > 0) { - register MESHPATCH *pp = ms->patch + ms->npatches; + MESHPATCH *pp = ms->patch + ms->npatches; while (pp-- > ms->patch) { if (pp->j2tri != NULL) free((void *)pp->j2tri); @@ -691,8 +730,7 @@ register MESH *ms; void -freemeshinst(o) /* free mesh instance */ -OBJREC *o; +freemeshinst(OBJREC *o) /* free mesh instance */ { if (o->os == NULL) return;