--- ray/src/common/mesh.c 2012/11/06 01:56:37 2.25 +++ ray/src/common/mesh.c 2018/11/27 06:20:37 2.31 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: mesh.c,v 2.25 2012/11/06 01:56:37 greg Exp $"; +static const char RCSid[] = "$Id: mesh.c,v 2.31 2018/11/27 06:20:37 greg Exp $"; #endif /* * Mesh support routines @@ -52,6 +52,7 @@ static int 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]) @@ -99,7 +100,7 @@ getmesh( /* get new mesh data reference */ } if ((pathname = getpath(mname, getrlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find mesh file \"%s\"", mname); - error(USER, errmsg); + error(SYSTEM, errmsg); } flags &= ~ms->ldflags; if (flags) @@ -148,41 +149,27 @@ nextmeshtri( /* get next triangle ID */ MESH *mp ) { - int advance = 1; int pn; MESHPATCH *pp; - if (*tip == OVOID) { /* check for first index */ - *tip = 0; - advance = 0; - } - pn = *tip >> 10; + 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 - advance) { - *tip += advance; + if ((*tip & 0x1ff) < pp->ntris) return(1); - } *tip &= ~0x1ff; /* move on to single-joiners */ *tip |= 0x200; - advance = 0; } if (!(*tip & 0x100)) { /* single joiner? */ - if ((*tip & 0xff) < pp->nj1tris - advance) { - *tip += advance; + if ((*tip & 0xff) < pp->nj1tris) return(1); - } *tip &= ~0xff; /* move on to double-joiners */ *tip |= 0x100; - advance = 0; } - if ((*tip & 0xff) < pp->nj2tris - advance) { - *tip += advance; + if ((*tip & 0xff) < pp->nj2tris) return(1); - } *tip = ++pn << 10; /* first in next patch */ - advance = 0; } return(0); /* out of patches */ } @@ -300,7 +287,7 @@ getmeshpseudo( /* get mesh pseudo object for materia OBJECT mo ) { - if (mo < mp->mat0 || mo >= mp->mat0 + mp->nmats) + if ((mo < mp->mat0) | (mo >= mp->mat0 + mp->nmats)) error(INTERNAL, "modifier out of range in getmeshpseudo"); if (mp->pseudo == NULL) { int i; @@ -341,12 +328,12 @@ getmeshtri( /* get triangle vertices */ int32 addmeshvert( /* find/add a mesh vertex */ - MESH *mp, + MESH *mp, MESHVERT *vp ) { - LUENT *lvp; - MCVERT cv; + LUENT *lvp; + MCVERT cv; int i; if (!(vp->fl & MT_V)) @@ -387,7 +374,7 @@ addmeshvert( /* find/add a mesh vertex */ goto nomem; if (lvp->key == NULL) { lvp->key = (char *)malloc(sizeof(MCVERT)+sizeof(int32)); - memcpy((void *)lvp->key, (void *)&cv, sizeof(MCVERT)); + memcpy(lvp->key, &cv, sizeof(MCVERT)); } if (lvp->data == NULL) { /* new vertex */ MESHPATCH *pp; @@ -398,16 +385,16 @@ addmeshvert( /* find/add a mesh vertex */ goto nomem; mp->npatches = 1; } else if (mp->patch[mp->npatches-1].nverts >= 256) { + if (mp->npatches >= 1L<<22) + error(INTERNAL, "too many mesh patches"); if (mp->npatches % MPATCHBLKSIZ == 0) { - mp->patch = (MESHPATCH *)realloc( - (void *)mp->patch, - (mp->npatches + MPATCHBLKSIZ)* - sizeof(MESHPATCH)); - memset((void *)(mp->patch + mp->npatches), '\0', + mp->patch = (MESHPATCH *)realloc(mp->patch, + (mp->npatches + MPATCHBLKSIZ)* + sizeof(MESHPATCH)); + memset((mp->patch + mp->npatches), '\0', MPATCHBLKSIZ*sizeof(MESHPATCH)); } - if (mp->npatches++ >= 1L<<22) - error(INTERNAL, "too many mesh patches"); + mp->npatches++; } pp = &mp->patch[mp->npatches-1]; if (pp->xyz == NULL) { @@ -453,8 +440,8 @@ addmeshtri( /* add a new mesh triangle */ OBJECT mo ) { - int32 vid[3], t; - int pn[3], i; + int32 vid[3], t; + int pn[3], i; MESHPATCH *pp; if (!(tv[0].fl & tv[1].fl & tv[2].fl & MT_V)) @@ -473,7 +460,7 @@ addmeshtri( /* add a new mesh triangle */ error(INTERNAL, "modifier range error in addmeshtri"); } /* assign triangle */ - if (pn[0] == pn[1] && pn[1] == pn[2]) { /* local case */ + if ((pn[0] == pn[1]) & (pn[1] == pn[2])) { /* local case */ pp = &mp->patch[pn[0]]; if (pp->tri == NULL) { pp->tri = (struct PTri *)malloc( @@ -499,8 +486,7 @@ addmeshtri( /* add a new mesh triangle */ pp->trimat[pp->ntris] = mo; return(pn[0] << 10 | pp->ntris++); } - } - if (pn[0] == pn[1]) { + } else if (pn[0] == pn[1]) { t = vid[2]; vid[2] = vid[1]; vid[1] = vid[0]; vid[0] = t; i = pn[2]; pn[2] = pn[1]; pn[1] = pn[0]; pn[0] = i; } else if (pn[0] == pn[2]) { @@ -524,20 +510,37 @@ addmeshtri( /* add a new mesh triangle */ } } /* double link */ - pp = &mp->patch[pn[2]]; + pp = &mp->patch[pn[i=0]]; + if (pp->nj2tris >= 256) + pp = &mp->patch[pn[i=1]]; + if (pp->nj2tris >= 256) + pp = &mp->patch[pn[i=2]]; + if (pp->nj2tris >= 256) + error(INTERNAL, "too many patch triangles in addmeshtri"); if (pp->j2tri == NULL) { pp->j2tri = (struct PJoin2 *)malloc( 256*sizeof(struct PJoin2)); if (pp->j2tri == NULL) goto nomem; } - if (pp->nj2tris >= 256) - error(INTERNAL, "too many patch triangles in addmeshtri"); - pp->j2tri[pp->nj2tris].v1j = vid[0]; - pp->j2tri[pp->nj2tris].v2j = vid[1]; - pp->j2tri[pp->nj2tris].v3 = vid[2] & 0xff; pp->j2tri[pp->nj2tris].mat = mo; - return(pn[2] << 10 | 0x300 | pp->nj2tris++); + switch (i) { + case 0: + pp->j2tri[pp->nj2tris].v3 = vid[0] & 0xff; + pp->j2tri[pp->nj2tris].v1j = vid[1]; + pp->j2tri[pp->nj2tris].v2j = vid[2]; + return(pn[0] << 10 | 0x300 | pp->nj2tris++); + case 1: + pp->j2tri[pp->nj2tris].v2j = vid[0]; + pp->j2tri[pp->nj2tris].v3 = vid[1] & 0xff; + pp->j2tri[pp->nj2tris].v1j = vid[2]; + return(pn[1] << 10 | 0x300 | pp->nj2tris++); + case 2: + pp->j2tri[pp->nj2tris].v1j = vid[0]; + pp->j2tri[pp->nj2tris].v2j = vid[1]; + pp->j2tri[pp->nj2tris].v3 = vid[2] & 0xff; + return(pn[2] << 10 | 0x300 | pp->nj2tris++); + } nomem: error(SYSTEM, "out of memory in addmeshtri"); return(OVOID); @@ -549,7 +552,7 @@ checkmesh(MESH *mp) /* validate mesh data */ { static char embuf[128]; int nouvbounds = 1; - int i; + int i; /* basic checks */ if (mp == NULL) return("NULL mesh pointer"); @@ -723,23 +726,25 @@ freemesh(MESH *ms) /* free mesh data */ MESHPATCH *pp = ms->patch + ms->npatches; while (pp-- > ms->patch) { if (pp->j2tri != NULL) - free((void *)pp->j2tri); + free(pp->j2tri); if (pp->j1tri != NULL) - free((void *)pp->j1tri); + free(pp->j1tri); if (pp->tri != NULL) - free((void *)pp->tri); + free(pp->tri); if (pp->uv != NULL) - free((void *)pp->uv); + free(pp->uv); if (pp->norm != NULL) - free((void *)pp->norm); + free(pp->norm); if (pp->xyz != NULL) - free((void *)pp->xyz); + free(pp->xyz); + if (pp->trimat != NULL) + free(pp->trimat); } - free((void *)ms->patch); + free(ms->patch); } if (ms->pseudo != NULL) - free((void *)ms->pseudo); - free((void *)ms); + free(ms->pseudo); + free(ms); } @@ -749,6 +754,6 @@ freemeshinst(OBJREC *o) /* free mesh instance */ if (o->os == NULL) return; freemesh((*(MESHINST *)o->os).msh); - free((void *)o->os); + free(o->os); o->os = NULL; }