| 1 | greg | 2.1 | /* RCSid $Id$ */ | 
| 2 |  |  | /* | 
| 3 |  |  | * Header for compact triangle mesh geometry | 
| 4 |  |  | * | 
| 5 |  |  | *  Include after standard.h, object.h and octree.h | 
| 6 |  |  | */ | 
| 7 |  |  |  | 
| 8 |  |  | #include "copyright.h" | 
| 9 |  |  |  | 
| 10 |  |  | #ifndef uint4 | 
| 11 |  |  | #define uint4   unsigned int4 | 
| 12 |  |  | #endif | 
| 13 |  |  | #ifndef BYTE | 
| 14 |  |  | #define BYTE    unsigned char | 
| 15 |  |  | #endif | 
| 16 |  |  |  | 
| 17 |  |  | /* | 
| 18 |  |  | * Vertex space is minimized without compromising accuracy by using a | 
| 19 |  |  | * 4-byte unsigned int to indicate position in the enclosing octree cube. | 
| 20 |  |  | * The same trick is used for any local (u,v) coordinates, whose limits | 
| 21 |  |  | * are recorded separately in the parent MESH structure.  The uvlimit's | 
| 22 |  |  | * in the MESH structure are set such that (0,0) is out of range, so | 
| 23 |  |  | * we use this to indicate an unspecified local coordinate. | 
| 24 |  |  | * A vertex normal, if specified, is stored in a single 4-byte | 
| 25 |  |  | * integer using the codec in dircode.c.  The encodedir() function | 
| 26 |  |  | * never generates 0, so we can use this for unspecified normals. | 
| 27 |  |  | * | 
| 28 |  |  | * Vertex ID's are encoded using the bottom 8 bits of a 4-byte integer | 
| 29 |  |  | * to index a vertex in a patch indicated by the 20 bits above (9-29). | 
| 30 |  |  | * For triangle ID's, the top 10 bits (11-31) indicate the patch, and | 
| 31 |  |  | * the 10th bit indicates whether the triangle joins patches. | 
| 32 |  |  | * If not, then the bottom 9 bits index into the local PTri array. | 
| 33 |  |  | * If it's a joiner, then the 9th bit indicates whether the triangle joins | 
| 34 |  |  | * two patches, in which case the bottom 8 bits index the PJoin2 array. | 
| 35 |  |  | * Otherwise, the bottom 8 bits index the PJoin1 array. | 
| 36 |  |  | * | 
| 37 |  |  | * These shenanigans minimize vertex reference memory requirements | 
| 38 |  |  | * in compiled mesh structures, where the octree leaves contain sets | 
| 39 |  |  | * of triangle ID's rather than the more usual objects.  It seems like | 
| 40 |  |  | * a lot of effort, but it can reduce mesh storage by a factor of 3 | 
| 41 |  |  | * or more.  This is important, as the whole point is to model very | 
| 42 |  |  | * complicated geometry with this structure, and memory is the main | 
| 43 |  |  | * limitation.  (We also optimize intersection tests for triangles.) | 
| 44 |  |  | */ | 
| 45 |  |  |  | 
| 46 |  |  | /* A triangle mesh patch */ | 
| 47 |  |  | typedef struct { | 
| 48 |  |  | uint4           (*xyz)[3];      /* up to 256 patch vertices */ | 
| 49 |  |  | int4            *norm;          /* vertex normals */ | 
| 50 |  |  | uint4           (*uv)[2];       /* vertex local coordinates */ | 
| 51 |  |  | struct PTri { | 
| 52 |  |  | BYTE            v1, v2, v3;     /* local vertices */ | 
| 53 |  |  | }               *tri;           /* local triangles */ | 
| 54 |  |  | struct PJoin1 { | 
| 55 |  |  | int4            v1j;            /* non-local vertex */ | 
| 56 |  |  | BYTE            v2, v3;         /* local vertices */ | 
| 57 |  |  | }               *j1tri;         /* joiner triangles */ | 
| 58 |  |  | struct PJoin2 { | 
| 59 |  |  | int4            v1j, v2j;       /* non-local vertices */ | 
| 60 |  |  | BYTE            v3;             /* local vertex */ | 
| 61 |  |  | }               *j2tri;         /* double joiner triangles */ | 
| 62 |  |  | short           nverts;         /* vertex count */ | 
| 63 |  |  | short           ntris;          /* triangle count */ | 
| 64 |  |  | short           nj1tris;        /* joiner triangle count */ | 
| 65 |  |  | short           nj2tris;        /* double joiner triangle count */ | 
| 66 |  |  | } MESHPATCH; | 
| 67 |  |  |  | 
| 68 |  |  | /* A loaded mesh */ | 
| 69 |  |  | typedef struct mesh { | 
| 70 |  |  | char            *name;          /* mesh file name */ | 
| 71 |  |  | int             nref;           /* reference count */ | 
| 72 |  |  | int             ldflags;        /* what we've loaded */ | 
| 73 |  |  | CUBE            mcube;          /* bounds and octree */ | 
| 74 |  |  | FLOAT           uvlim[2][2];    /* local coordinate extrema */ | 
| 75 |  |  | MESHPATCH       *patch;         /* mesh patch list */ | 
| 76 |  |  | int             npatches;       /* number of mesh patches */ | 
| 77 |  |  | char            *cdata;         /* opaque client data pointer */ | 
| 78 |  |  | struct mesh     *next;          /* next mesh in list */ | 
| 79 |  |  | } MESH; | 
| 80 |  |  |  | 
| 81 |  |  | /* A mesh instance */ | 
| 82 |  |  | typedef struct { | 
| 83 |  |  | FULLXF          x;              /* forward and backward transforms */ | 
| 84 |  |  | MESH            *msh;           /* mesh object reference */ | 
| 85 |  |  | } MESHINST; | 
| 86 |  |  |  | 
| 87 |  |  | /* vertex flags */ | 
| 88 |  |  | #define MT_V            01 | 
| 89 |  |  | #define MT_N            02 | 
| 90 |  |  | #define MT_UV           04 | 
| 91 |  |  | #define MT_ALL          07 | 
| 92 |  |  |  | 
| 93 |  |  | /* A mesh vertex */ | 
| 94 |  |  | typedef struct { | 
| 95 |  |  | int             fl;             /* setting flags */ | 
| 96 |  |  | FVECT           v;              /* vertex location */ | 
| 97 |  |  | FVECT           n;              /* vertex normal */ | 
| 98 |  |  | FLOAT           uv[2];          /* local coordinates */ | 
| 99 |  |  | } MESHVERT; | 
| 100 |  |  |  | 
| 101 |  |  | /* mesh format identifier */ | 
| 102 |  |  | #define MESHFMT         "Radiance_tmesh" | 
| 103 |  |  | /* magic number for mesh files */ | 
| 104 |  |  | #define MESHMAGIC       ( 0 *MAXOBJSIZ+311)     /* increment first value */ | 
| 105 |  |  |  | 
| 106 |  |  | #ifdef NOPROTO | 
| 107 |  |  |  | 
| 108 |  |  | extern MESH     *getmesh(); | 
| 109 |  |  | extern INSTANCE *getmeshinst(); | 
| 110 |  |  | extern int      getmeshtrivid(); | 
| 111 |  |  | extern int      getmeshvert(); | 
| 112 |  |  | extern int      getmeshtri(); | 
| 113 |  |  | extern int4     addmeshvert(); | 
| 114 |  |  | extern OBJECT   addmeshtri(); | 
| 115 |  |  | extern void     printmeshstats(); | 
| 116 |  |  | extern void     freemesh(); | 
| 117 |  |  | extern void     freemeshinst(); | 
| 118 |  |  | extern void     readmesh(); | 
| 119 |  |  | extern void     writemesh(); | 
| 120 |  |  |  | 
| 121 |  |  | #else | 
| 122 |  |  |  | 
| 123 |  |  | extern MESH     *getmesh(char *mname, int flags); | 
| 124 |  |  | extern MESHINST *getmeshinst(OBJREC *o, int flags); | 
| 125 |  |  | extern int      getmeshtrivid(int4 tvid[3], MESH *mp, OBJECT ti); | 
| 126 |  |  | extern int      getmeshvert(MESHVERT *vp, MESH *mp, int4 vid, int what); | 
| 127 |  |  | extern int      getmeshtri(MESHVERT tv[3], MESH *mp, OBJECT ti, int what); | 
| 128 |  |  | extern int4     addmeshvert(MESH *mp, MESHVERT *vp); | 
| 129 |  |  | extern OBJECT   addmeshtri(MESH *mp, MESHVERT tv[3]); | 
| 130 |  |  | extern void     printmeshstats(MESH *ms, FILE *fp); | 
| 131 |  |  | extern void     freemesh(MESH *ms); | 
| 132 |  |  | extern void     freemeshinst(OBJREC *o); | 
| 133 |  |  | extern void     readmesh(MESH *mp, char *path, int flags); | 
| 134 |  |  | extern void     writemesh(MESH *mp, FILE *fp); | 
| 135 |  |  |  | 
| 136 |  |  | #endif /* NOPROTO */ |