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