| 5 | 
  | 
 *  Routines for reading a compiled mesh from a file | 
| 6 | 
  | 
 */ | 
| 7 | 
  | 
 | 
| 8 | 
+ | 
#include  <time.h> | 
| 9 | 
+ | 
 | 
| 10 | 
+ | 
#include  "platform.h" | 
| 11 | 
  | 
#include  "standard.h" | 
| 12 | 
  | 
#include  "octree.h" | 
| 13 | 
  | 
#include  "object.h" | 
| 14 | 
  | 
#include  "mesh.h" | 
| 15 | 
+ | 
#include  "resolu.h" | 
| 16 | 
  | 
 | 
| 17 | 
  | 
static char     *meshfn;        /* input file name */ | 
| 18 | 
  | 
static FILE     *meshfp;        /* mesh file pointer */ | 
| 35 | 
  | 
mgetint(siz)                            /* get a siz-byte integer */ | 
| 36 | 
  | 
int  siz; | 
| 37 | 
  | 
{ | 
| 38 | 
< | 
        register long  r; | 
| 38 | 
> | 
        long  r = getint(siz, meshfp); | 
| 39 | 
  | 
 | 
| 40 | 
< | 
        r = getint(siz, meshfp); | 
| 37 | 
< | 
        if (feof(meshfp)) | 
| 40 | 
> | 
        if (r == EOF && feof(meshfp)) | 
| 41 | 
  | 
                mesherror(USER, "truncated mesh file"); | 
| 42 | 
+ | 
 | 
| 43 | 
  | 
        return(r); | 
| 44 | 
  | 
} | 
| 45 | 
  | 
 | 
| 47 | 
  | 
static double | 
| 48 | 
  | 
mgetflt()                               /* get a floating point number */ | 
| 49 | 
  | 
{ | 
| 50 | 
< | 
        double  r; | 
| 50 | 
> | 
        double  r = getflt(meshfp); | 
| 51 | 
  | 
 | 
| 52 | 
< | 
        r = getflt(meshfp); | 
| 49 | 
< | 
        if (feof(meshfp)) | 
| 52 | 
> | 
        if (r == (double)EOF && feof(meshfp)) | 
| 53 | 
  | 
                mesherror(USER, "truncated mesh file"); | 
| 54 | 
+ | 
 | 
| 55 | 
  | 
        return(r); | 
| 56 | 
  | 
} | 
| 57 | 
  | 
         | 
| 60 | 
  | 
getfullnode()                           /* get a set, return fullnode */ | 
| 61 | 
  | 
{ | 
| 62 | 
  | 
        OBJECT  set[MAXSET+1]; | 
| 63 | 
< | 
        register int  i; | 
| 63 | 
> | 
        int  i; | 
| 64 | 
  | 
 | 
| 65 | 
  | 
        if ((set[0] = mgetint(objsize)) > MAXSET) | 
| 66 | 
  | 
                mesherror(USER, "bad set in getfullnode"); | 
| 73 | 
  | 
static OCTREE | 
| 74 | 
  | 
gettree()                               /* get a pre-ordered octree */ | 
| 75 | 
  | 
{ | 
| 76 | 
< | 
        register OCTREE  ot; | 
| 77 | 
< | 
        register int  i; | 
| 76 | 
> | 
        OCTREE   ot; | 
| 77 | 
> | 
        int  i; | 
| 78 | 
  | 
         | 
| 79 | 
  | 
        switch (getc(meshfp)) { | 
| 80 | 
< | 
        case OT_EMPTY: | 
| 81 | 
< | 
                return(EMPTY); | 
| 82 | 
< | 
        case OT_FULL: | 
| 83 | 
< | 
                return(getfullnode()); | 
| 84 | 
< | 
        case OT_TREE: | 
| 85 | 
< | 
                if ((ot = octalloc()) == EMPTY) | 
| 86 | 
< | 
                        mesherror(SYSTEM, "out of tree space in readmesh"); | 
| 87 | 
< | 
                for (i = 0; i < 8; i++) | 
| 88 | 
< | 
                        octkid(ot, i) = gettree(); | 
| 89 | 
< | 
                return(ot); | 
| 90 | 
< | 
        case EOF: | 
| 91 | 
< | 
                mesherror(USER, "truncated mesh octree"); | 
| 92 | 
< | 
        default: | 
| 93 | 
< | 
                mesherror(USER, "damaged mesh octree"); | 
| 80 | 
> | 
                case OT_EMPTY: | 
| 81 | 
> | 
                        return(EMPTY); | 
| 82 | 
> | 
                case OT_FULL: | 
| 83 | 
> | 
                        return(getfullnode()); | 
| 84 | 
> | 
                case OT_TREE: | 
| 85 | 
> | 
                        if ((ot = octalloc()) == EMPTY) | 
| 86 | 
> | 
                                mesherror(SYSTEM, "out of tree space in readmesh"); | 
| 87 | 
> | 
                        for (i = 0; i < 8; i++) | 
| 88 | 
> | 
                                octkid(ot, i) = gettree(); | 
| 89 | 
> | 
                        return(ot); | 
| 90 | 
> | 
                case EOF: | 
| 91 | 
> | 
                        mesherror(USER, "truncated mesh octree"); | 
| 92 | 
> | 
                default: | 
| 93 | 
> | 
                        mesherror(USER, "damaged mesh octree"); | 
| 94 | 
  | 
        } | 
| 95 | 
+ | 
        return (OCTREE)0;       /* pro forma return */ | 
| 96 | 
  | 
} | 
| 97 | 
  | 
 | 
| 98 | 
  | 
 | 
| 99 | 
  | 
static void | 
| 100 | 
  | 
skiptree()                              /* skip octree on input */ | 
| 101 | 
  | 
{ | 
| 102 | 
< | 
        register int  i; | 
| 102 | 
> | 
        int  i; | 
| 103 | 
  | 
         | 
| 104 | 
  | 
        switch (getc(meshfp)) { | 
| 105 | 
  | 
        case OT_EMPTY: | 
| 123 | 
  | 
 | 
| 124 | 
  | 
static void | 
| 125 | 
  | 
getpatch(pp)                            /* load a mesh patch */ | 
| 126 | 
< | 
register MESHPATCH      *pp; | 
| 126 | 
> | 
MESHPATCH       *pp; | 
| 127 | 
  | 
{ | 
| 128 | 
  | 
        int     flags; | 
| 129 | 
  | 
        int     i, j; | 
| 133 | 
  | 
                mesherror(USER, "bad patch flags"); | 
| 134 | 
  | 
                                        /* allocate vertices */ | 
| 135 | 
  | 
        pp->nverts = mgetint(2); | 
| 136 | 
< | 
        if (pp->nverts <= 0 || pp->nverts > 256) | 
| 136 | 
> | 
        if ((pp->nverts <= 0) | (pp->nverts > 256)) | 
| 137 | 
  | 
                mesherror(USER, "bad number of patch vertices"); | 
| 138 | 
< | 
        pp->xyz = (uint4 (*)[3])malloc(pp->nverts*3*sizeof(uint4)); | 
| 138 | 
> | 
        pp->xyz = (uint32 (*)[3])malloc(pp->nverts*3*sizeof(uint32)); | 
| 139 | 
  | 
        if (pp->xyz == NULL) | 
| 140 | 
  | 
                goto nomem; | 
| 141 | 
  | 
        if (flags & MT_N) { | 
| 142 | 
< | 
                pp->norm = (int4 *)calloc(pp->nverts, sizeof(int4)); | 
| 142 | 
> | 
                pp->norm = (int32 *)calloc(pp->nverts, sizeof(int32)); | 
| 143 | 
  | 
                if (pp->norm == NULL) | 
| 144 | 
  | 
                        goto nomem; | 
| 145 | 
  | 
        } else | 
| 146 | 
  | 
                pp->norm = NULL; | 
| 147 | 
  | 
        if (flags & MT_UV) { | 
| 148 | 
< | 
                pp->uv = (uint4 (*)[2])calloc(pp->nverts, 2*sizeof(uint4)); | 
| 148 | 
> | 
                pp->uv = (uint32 (*)[2])calloc(pp->nverts, 2*sizeof(uint32)); | 
| 149 | 
  | 
                if (pp->uv == NULL) | 
| 150 | 
  | 
                        goto nomem; | 
| 151 | 
  | 
        } else | 
| 165 | 
  | 
                                pp->uv[i][j] = mgetint(4); | 
| 166 | 
  | 
                                        /* local triangles */ | 
| 167 | 
  | 
        pp->ntris = mgetint(2); | 
| 168 | 
< | 
        if (pp->ntris < 0 || pp->ntris > 512) | 
| 168 | 
> | 
        if ((pp->ntris < 0) | (pp->ntris > 512)) | 
| 169 | 
  | 
                mesherror(USER, "bad number of local triangles"); | 
| 170 | 
  | 
        if (pp->ntris) { | 
| 171 | 
  | 
                pp->tri = (struct PTri *)malloc(pp->ntris * | 
| 181 | 
  | 
                pp->tri = NULL; | 
| 182 | 
  | 
                                        /* local triangle material(s) */ | 
| 183 | 
  | 
        if (mgetint(2) > 1) { | 
| 184 | 
< | 
                pp->trimat = (int2 *)malloc(pp->ntris*sizeof(int2)); | 
| 184 | 
> | 
                pp->trimat = (int16 *)malloc(pp->ntris*sizeof(int16)); | 
| 185 | 
  | 
                if (pp->trimat == NULL) | 
| 186 | 
  | 
                        goto nomem; | 
| 187 | 
  | 
                for (i = 0; i < pp->ntris; i++) | 
| 192 | 
  | 
        } | 
| 193 | 
  | 
                                        /* joiner triangles */ | 
| 194 | 
  | 
        pp->nj1tris = mgetint(2); | 
| 195 | 
< | 
        if (pp->nj1tris < 0 || pp->nj1tris > 512) | 
| 195 | 
> | 
        if ((pp->nj1tris < 0) | (pp->nj1tris > 256)) | 
| 196 | 
  | 
                mesherror(USER, "bad number of joiner triangles"); | 
| 197 | 
  | 
        if (pp->nj1tris) { | 
| 198 | 
  | 
                pp->j1tri = (struct PJoin1 *)malloc(pp->nj1tris * | 
| 209 | 
  | 
                pp->j1tri = NULL; | 
| 210 | 
  | 
                                        /* double joiner triangles */ | 
| 211 | 
  | 
        pp->nj2tris = mgetint(2); | 
| 212 | 
< | 
        if (pp->nj2tris < 0 || pp->nj2tris > 256) | 
| 212 | 
> | 
        if ((pp->nj2tris < 0) | (pp->nj2tris > 256)) | 
| 213 | 
  | 
                mesherror(USER, "bad number of double joiner triangles"); | 
| 214 | 
  | 
        if (pp->nj2tris) { | 
| 215 | 
  | 
                pp->j2tri = (struct PJoin2 *)malloc(pp->nj2tris * | 
| 249 | 
  | 
                sprintf(errmsg, "cannot open mesh file \"%s\"", path); | 
| 250 | 
  | 
                error(SYSTEM, errmsg); | 
| 251 | 
  | 
        } | 
| 252 | 
< | 
#ifdef MSDOS | 
| 253 | 
< | 
        setmode(fileno(meshfp), O_BINARY); | 
| 252 | 
> | 
        SET_FILE_BINARY(meshfp); | 
| 253 | 
> | 
#ifdef getc_unlocked                    /* avoid stupid semaphores */ | 
| 254 | 
> | 
        flockfile(meshfp); | 
| 255 | 
  | 
#endif | 
| 256 | 
  | 
                                        /* read header */ | 
| 257 | 
  | 
        checkheader(meshfp, MESHFMT, flags&IO_INFO ? stdout : (FILE *)NULL); | 
| 258 | 
  | 
                                        /* read format number */ | 
| 259 | 
  | 
        objsize = getint(2, meshfp) - MESHMAGIC; | 
| 260 | 
< | 
        if (objsize <= 0 || objsize > MAXOBJSIZ || objsize > sizeof(long)) | 
| 260 | 
> | 
        if ((objsize <= 0) | (objsize > MAXOBJSIZ) | (objsize > sizeof(long))) | 
| 261 | 
  | 
                mesherror(USER, "incompatible mesh format"); | 
| 262 | 
  | 
                                        /* read boundaries */ | 
| 263 | 
  | 
        if (flags & IO_BOUNDS) { | 
| 293 | 
  | 
                        getpatch(&mp->patch[i]); | 
| 294 | 
  | 
        } | 
| 295 | 
  | 
                                        /* clean up */ | 
| 296 | 
< | 
        fclose(meshfp); | 
| 296 | 
> | 
        if (meshfp != stdin) | 
| 297 | 
> | 
                fclose(meshfp); | 
| 298 | 
> | 
#ifdef getc_unlocked | 
| 299 | 
> | 
        else | 
| 300 | 
> | 
                funlockfile(meshfp); | 
| 301 | 
> | 
#endif | 
| 302 | 
  | 
        mp->ldflags |= flags; | 
| 303 | 
  | 
                                        /* verify data */ | 
| 304 | 
  | 
        if ((err = checkmesh(mp)) != NULL) |