| 1 | schorsch | 2.7 | /* RCSid $Id: mesh.h,v 2.6 2003/06/20 00:25:49 greg Exp $ */ | 
| 2 | greg | 2.1 | /* | 
| 3 |  |  | * Header for compact triangle mesh geometry | 
| 4 |  |  | * | 
| 5 |  |  | *  Include after standard.h, object.h and octree.h | 
| 6 |  |  | */ | 
| 7 | schorsch | 2.5 | #ifndef _RAD_MESH_H_ | 
| 8 |  |  | #define _RAD_MESH_H_ | 
| 9 |  |  | #ifdef __cplusplus | 
| 10 |  |  | extern "C" { | 
| 11 |  |  | #endif | 
| 12 | greg | 2.1 |  | 
| 13 |  |  | #include "copyright.h" | 
| 14 |  |  |  | 
| 15 | greg | 2.3 | #include "lookup.h" | 
| 16 |  |  |  | 
| 17 | greg | 2.1 | #ifndef BYTE | 
| 18 |  |  | #define BYTE    unsigned char | 
| 19 |  |  | #endif | 
| 20 |  |  |  | 
| 21 |  |  | /* | 
| 22 |  |  | * Vertex space is minimized without compromising accuracy by using a | 
| 23 |  |  | * 4-byte unsigned int to indicate position in the enclosing octree cube. | 
| 24 |  |  | * The same trick is used for any local (u,v) coordinates, whose limits | 
| 25 |  |  | * are recorded separately in the parent MESH structure.  The uvlimit's | 
| 26 |  |  | * in the MESH structure are set such that (0,0) is out of range, so | 
| 27 |  |  | * we use this to indicate an unspecified local coordinate. | 
| 28 |  |  | * A vertex normal, if specified, is stored in a single 4-byte | 
| 29 |  |  | * integer using the codec in dircode.c.  The encodedir() function | 
| 30 |  |  | * never generates 0, so we can use this for unspecified normals. | 
| 31 |  |  | * | 
| 32 |  |  | * Vertex ID's are encoded using the bottom 8 bits of a 4-byte integer | 
| 33 | greg | 2.2 | * to index a vertex in a patch indicated by the 22 bits above (8-29). | 
| 34 |  |  | * For triangle ID's, the top 22 bits (10-31) indicate the patch, and | 
| 35 |  |  | * the bit 9 (0x200) indicates whether the triangle joins patches. | 
| 36 | greg | 2.1 | * If not, then the bottom 9 bits index into the local PTri array. | 
| 37 | greg | 2.2 | * If it's a joiner, then the 8th bit indicates whether the triangle joins | 
| 38 | greg | 2.1 | * two patches, in which case the bottom 8 bits index the PJoin2 array. | 
| 39 |  |  | * Otherwise, the bottom 8 bits index the PJoin1 array. | 
| 40 |  |  | * | 
| 41 |  |  | * These shenanigans minimize vertex reference memory requirements | 
| 42 |  |  | * in compiled mesh structures, where the octree leaves contain sets | 
| 43 |  |  | * of triangle ID's rather than the more usual objects.  It seems like | 
| 44 |  |  | * a lot of effort, but it can reduce mesh storage by a factor of 3 | 
| 45 |  |  | * or more.  This is important, as the whole point is to model very | 
| 46 |  |  | * complicated geometry with this structure, and memory is the main | 
| 47 | greg | 2.3 | * limitation. | 
| 48 | greg | 2.1 | */ | 
| 49 |  |  |  | 
| 50 |  |  | /* A triangle mesh patch */ | 
| 51 |  |  | typedef struct { | 
| 52 | greg | 2.6 | uint32          (*xyz)[3];      /* up to 256 patch vertices */ | 
| 53 |  |  | int32           *norm;          /* vertex normals */ | 
| 54 |  |  | uint32          (*uv)[2];       /* vertex local coordinates */ | 
| 55 | greg | 2.1 | struct PTri { | 
| 56 |  |  | BYTE            v1, v2, v3;     /* local vertices */ | 
| 57 |  |  | }               *tri;           /* local triangles */ | 
| 58 | greg | 2.3 | short           solemat;        /* sole material */ | 
| 59 | greg | 2.6 | int16           *trimat;        /* or local material indices */ | 
| 60 | greg | 2.1 | struct PJoin1 { | 
| 61 | greg | 2.6 | int32           v1j;            /* non-local vertex */ | 
| 62 |  |  | int16           mat;            /* material index */ | 
| 63 | greg | 2.1 | BYTE            v2, v3;         /* local vertices */ | 
| 64 |  |  | }               *j1tri;         /* joiner triangles */ | 
| 65 |  |  | struct PJoin2 { | 
| 66 | greg | 2.6 | int32           v1j, v2j;       /* non-local vertices */ | 
| 67 |  |  | int16           mat;            /* material index */ | 
| 68 | greg | 2.1 | BYTE            v3;             /* local vertex */ | 
| 69 |  |  | }               *j2tri;         /* double joiner triangles */ | 
| 70 |  |  | short           nverts;         /* vertex count */ | 
| 71 |  |  | short           ntris;          /* 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 | schorsch | 2.7 | RREAL           uvlim[2][2];    /* local coordinate extrema */ | 
| 83 | greg | 2.3 | OBJECT          mat0;           /* base material index */ | 
| 84 |  |  | OBJECT          nmats;          /* number of materials */ | 
| 85 | greg | 2.1 | MESHPATCH       *patch;         /* mesh patch list */ | 
| 86 |  |  | int             npatches;       /* number of mesh patches */ | 
| 87 | greg | 2.3 | OBJREC          *pseudo;        /* mesh pseudo objects */ | 
| 88 |  |  | LUTAB           lut;            /* vertex lookup table */ | 
| 89 | greg | 2.1 | 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 | schorsch | 2.7 | RREAL           uv[2];          /* local coordinates */ | 
| 110 | greg | 2.1 | } MESHVERT; | 
| 111 |  |  |  | 
| 112 |  |  | /* mesh format identifier */ | 
| 113 |  |  | #define MESHFMT         "Radiance_tmesh" | 
| 114 |  |  | /* magic number for mesh files */ | 
| 115 | greg | 2.3 | #define MESHMAGIC       ( 1 *MAXOBJSIZ+311)     /* increment first value */ | 
| 116 | greg | 2.1 |  | 
| 117 |  |  |  | 
| 118 |  |  | extern MESH     *getmesh(char *mname, int flags); | 
| 119 |  |  | extern MESHINST *getmeshinst(OBJREC *o, int flags); | 
| 120 | greg | 2.6 | extern int      getmeshtrivid(int32 tvid[3], OBJECT *mo, | 
| 121 | greg | 2.3 | MESH *mp, OBJECT ti); | 
| 122 | greg | 2.6 | extern int      getmeshvert(MESHVERT *vp, MESH *mp, int32 vid, int what); | 
| 123 | greg | 2.3 | extern int      getmeshtri(MESHVERT tv[3], OBJECT *mo, | 
| 124 |  |  | MESH *mp, OBJECT ti, int what); | 
| 125 |  |  | extern OBJREC   *getmeshpseudo(MESH *mp, OBJECT mo); | 
| 126 | greg | 2.6 | extern int32    addmeshvert(MESH *mp, MESHVERT *vp); | 
| 127 | greg | 2.3 | extern OBJECT   addmeshtri(MESH *mp, MESHVERT tv[3], OBJECT mo); | 
| 128 |  |  | extern char     *checkmesh(MESH *mp); | 
| 129 | greg | 2.1 | extern void     printmeshstats(MESH *ms, FILE *fp); | 
| 130 |  |  | extern void     freemesh(MESH *ms); | 
| 131 |  |  | extern void     freemeshinst(OBJREC *o); | 
| 132 |  |  | extern void     readmesh(MESH *mp, char *path, int flags); | 
| 133 |  |  | extern void     writemesh(MESH *mp, FILE *fp); | 
| 134 |  |  |  | 
| 135 | schorsch | 2.5 |  | 
| 136 |  |  | #ifdef __cplusplus | 
| 137 |  |  | } | 
| 138 |  |  | #endif | 
| 139 |  |  | #endif /* _RAD_MESH_H_ */ | 
| 140 |  |  |  |