--- ray/src/common/readmesh.c 2003/03/11 17:08:55 2.1 +++ ray/src/common/readmesh.c 2023/02/07 20:28:16 2.19 @@ -1,14 +1,18 @@ #ifndef lint -static const char RCSid[] = "$Id: readmesh.c,v 2.1 2003/03/11 17:08:55 greg Exp $"; +static const char RCSid[] = "$Id: readmesh.c,v 2.19 2023/02/07 20:28:16 greg Exp $"; #endif /* * Routines for reading a compiled mesh from a file */ +#include + +#include "platform.h" #include "standard.h" #include "octree.h" #include "object.h" #include "mesh.h" +#include "resolu.h" static char *meshfn; /* input file name */ static FILE *meshfp; /* mesh file pointer */ @@ -31,11 +35,11 @@ static long mgetint(siz) /* get a siz-byte integer */ int siz; { - register long r; + long r = getint(siz, meshfp); - r = getint(siz, meshfp); - if (feof(meshfp)) + if (r == EOF && feof(meshfp)) mesherror(USER, "truncated mesh file"); + return(r); } @@ -43,11 +47,11 @@ int siz; static double mgetflt() /* get a floating point number */ { - double r; + double r = getflt(meshfp); - r = getflt(meshfp); - if (feof(meshfp)) + if (r == (double)EOF && feof(meshfp)) mesherror(USER, "truncated mesh file"); + return(r); } @@ -56,7 +60,7 @@ static OCTREE getfullnode() /* get a set, return fullnode */ { OBJECT set[MAXSET+1]; - register int i; + int i; if ((set[0] = mgetint(objsize)) > MAXSET) mesherror(USER, "bad set in getfullnode"); @@ -69,32 +73,33 @@ getfullnode() /* get a set, return fullnode */ static OCTREE gettree() /* get a pre-ordered octree */ { - register OCTREE ot; - register int i; + OCTREE ot; + int i; switch (getc(meshfp)) { - case OT_EMPTY: - return(EMPTY); - case OT_FULL: - return(getfullnode()); - case OT_TREE: - if ((ot = octalloc()) == EMPTY) - mesherror(SYSTEM, "out of tree space in readmesh"); - for (i = 0; i < 8; i++) - octkid(ot, i) = gettree(); - return(ot); - case EOF: - mesherror(USER, "truncated mesh octree"); - default: - mesherror(USER, "damaged mesh octree"); + case OT_EMPTY: + return(EMPTY); + case OT_FULL: + return(getfullnode()); + case OT_TREE: + if ((ot = octalloc()) == EMPTY) + mesherror(SYSTEM, "out of tree space in readmesh"); + for (i = 0; i < 8; i++) + octkid(ot, i) = gettree(); + return(ot); + case EOF: + mesherror(USER, "truncated mesh octree"); + default: + mesherror(USER, "damaged mesh octree"); } + return (OCTREE)0; /* pro forma return */ } static void skiptree() /* skip octree on input */ { - register int i; + int i; switch (getc(meshfp)) { case OT_EMPTY: @@ -118,7 +123,7 @@ skiptree() /* skip octree on input */ static void getpatch(pp) /* load a mesh patch */ -register MESHPATCH *pp; +MESHPATCH *pp; { int flags; int i, j; @@ -128,19 +133,19 @@ register MESHPATCH *pp; mesherror(USER, "bad patch flags"); /* allocate vertices */ pp->nverts = mgetint(2); - if (pp->nverts <= 0 || pp->nverts > 256) + if ((pp->nverts <= 0) | (pp->nverts > 256)) mesherror(USER, "bad number of patch vertices"); - pp->xyz = (uint4 (*)[3])malloc(pp->nverts*3*sizeof(uint4)); + pp->xyz = (uint32 (*)[3])malloc(pp->nverts*3*sizeof(uint32)); if (pp->xyz == NULL) goto nomem; if (flags & MT_N) { - pp->norm = (int4 *)calloc(pp->nverts, sizeof(int4)); + pp->norm = (int32 *)calloc(pp->nverts, sizeof(int32)); if (pp->norm == NULL) goto nomem; } else pp->norm = NULL; if (flags & MT_UV) { - pp->uv = (uint4 (*)[2])calloc(pp->nverts, 2*sizeof(uint4)); + pp->uv = (uint32 (*)[2])calloc(pp->nverts, 2*sizeof(uint32)); if (pp->uv == NULL) goto nomem; } else @@ -160,7 +165,7 @@ register MESHPATCH *pp; pp->uv[i][j] = mgetint(4); /* local triangles */ pp->ntris = mgetint(2); - if (pp->ntris < 0 || pp->ntris > 512) + if ((pp->ntris < 0) | (pp->ntris > 512)) mesherror(USER, "bad number of local triangles"); if (pp->ntris) { pp->tri = (struct PTri *)malloc(pp->ntris * @@ -174,9 +179,20 @@ register MESHPATCH *pp; } } else pp->tri = NULL; + /* local triangle material(s) */ + if (mgetint(2) > 1) { + pp->trimat = (int16 *)malloc(pp->ntris*sizeof(int16)); + if (pp->trimat == NULL) + goto nomem; + for (i = 0; i < pp->ntris; i++) + pp->trimat[i] = mgetint(2); + } else { + pp->solemat = mgetint(2); + pp->trimat = NULL; + } /* joiner triangles */ pp->nj1tris = mgetint(2); - if (pp->nj1tris < 0 || pp->nj1tris > 512) + if ((pp->nj1tris < 0) | (pp->nj1tris > 256)) mesherror(USER, "bad number of joiner triangles"); if (pp->nj1tris) { pp->j1tri = (struct PJoin1 *)malloc(pp->nj1tris * @@ -187,12 +203,13 @@ register MESHPATCH *pp; pp->j1tri[i].v1j = mgetint(4); pp->j1tri[i].v2 = mgetint(1); pp->j1tri[i].v3 = mgetint(1); + pp->j1tri[i].mat = mgetint(2); } } else pp->j1tri = NULL; /* double joiner triangles */ pp->nj2tris = mgetint(2); - if (pp->nj2tris < 0 || pp->nj2tris > 256) + if ((pp->nj2tris < 0) | (pp->nj2tris > 256)) mesherror(USER, "bad number of double joiner triangles"); if (pp->nj2tris) { pp->j2tri = (struct PJoin2 *)malloc(pp->nj2tris * @@ -203,6 +220,7 @@ register MESHPATCH *pp; pp->j2tri[i].v1j = mgetint(4); pp->j2tri[i].v2j = mgetint(4); pp->j2tri[i].v3 = mgetint(1); + pp->j2tri[i].mat = mgetint(2); } } else pp->j2tri = NULL; @@ -218,6 +236,7 @@ MESH *mp; char *path; int flags; { + char *err; char sbuf[64]; int i; /* check what's loaded */ @@ -230,14 +249,15 @@ int flags; sprintf(errmsg, "cannot open mesh file \"%s\"", path); error(SYSTEM, errmsg); } -#ifdef MSDOS - setmode(fileno(meshfp), O_BINARY); + SET_FILE_BINARY(meshfp); +#ifdef getc_unlocked /* avoid stupid semaphores */ + flockfile(meshfp); #endif /* read header */ checkheader(meshfp, MESHFMT, flags&IO_INFO ? stdout : (FILE *)NULL); /* read format number */ objsize = getint(2, meshfp) - MESHMAGIC; - if (objsize <= 0 || objsize > MAXOBJSIZ || objsize > sizeof(long)) + if ((objsize <= 0) | (objsize > MAXOBJSIZ) | (objsize > sizeof(long))) mesherror(USER, "incompatible mesh format"); /* read boundaries */ if (flags & IO_BOUNDS) { @@ -259,8 +279,11 @@ int flags; mp->mcube.cutree = gettree(); else if (flags & IO_SCENE) skiptree(); - /* read the patches */ + /* read materials and patches */ if (flags & IO_SCENE) { + mp->mat0 = nobjects; + readscene(meshfp, objsize); + mp->nmats = nobjects - mp->mat0; mp->npatches = mgetint(4); mp->patch = (MESHPATCH *)calloc(mp->npatches, sizeof(MESHPATCH)); @@ -270,6 +293,14 @@ int flags; getpatch(&mp->patch[i]); } /* clean up */ - fclose(meshfp); + if (meshfp != stdin) + fclose(meshfp); +#ifdef getc_unlocked + else + funlockfile(meshfp); +#endif mp->ldflags |= flags; + /* verify data */ + if ((err = checkmesh(mp)) != NULL) + mesherror(USER, err); }