| 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_ */ |