Back to index

radiance  4R0+20100331
mesh.h
Go to the documentation of this file.
00001 /* RCSid $Id: mesh.h,v 2.13 2004/12/03 18:36:17 greg Exp $ */
00002 /*
00003  * Header for compact triangle mesh geometry
00004  *
00005  *  Include after standard.h, object.h and octree.h
00006  */
00007 #ifndef _RAD_MESH_H_
00008 #define _RAD_MESH_H_
00009 
00010 #include "lookup.h"
00011 
00012 #ifdef __cplusplus
00013 extern "C" {
00014 #endif
00015 
00016 #ifndef BYTE
00017 #define BYTE  unsigned char
00018 #endif
00019 
00020 /*
00021  * Vertex space is minimized without compromising accuracy by using a
00022  * 4-byte unsigned int to indicate position in the enclosing octree cube.
00023  * The same trick is used for any local (u,v) coordinates, whose limits
00024  * are recorded separately in the parent MESH structure.  The uvlimit's
00025  * in the MESH structure are set such that (0,0) is out of range, so
00026  * we use this to indicate an unspecified local coordinate.
00027  * A vertex normal, if specified, is stored in a single 4-byte
00028  * integer using the codec in dircode.c.  The encodedir() function
00029  * never generates 0, so we can use this for unspecified normals.
00030  *
00031  * Vertex ID's are encoded using the bottom 8 bits of a 4-byte integer
00032  * to index a vertex in a patch indicated by the 22 bits above (8-29).
00033  * For triangle ID's, the top 22 bits (10-31) indicate the parent patch,
00034  * and the 10th bit (0x200) indicates whether the triangle joins patches.
00035  * If not, then the bottom 9 bits index into the local PTri array.
00036  * If it's a joiner, then the 9th bit indicates whether the triangle joins
00037  * two patches, in which case the bottom 8 bits index the PJoin2 array.
00038  * Otherwise, the bottom 8 bits index the PJoin1 array.
00039  *
00040  * These shenanigans minimize vertex reference memory requirements
00041  * in compiled mesh structures, where the octree leaves contain sets 
00042  * of triangle ID's rather than the more usual objects.  It seems like
00043  * a lot of effort, but it can reduce mesh storage by a factor of 3
00044  * or more.  This is important, as the whole point is to model very
00045  * complicated geometry with this structure, and memory is the main
00046  * limitation.  (This representation is so efficient, that the octree
00047  * structure ends up dominating memory for most compiled meshes.)
00048  */
00049 
00050 /* A triangle mesh patch */
00051 typedef struct {
00052        uint32        (*xyz)[3];    /* up to 256 patch vertices */
00053        int32         *norm;        /* vertex normals */
00054        uint32        (*uv)[2];     /* vertex local coordinates */
00055        struct PTri {
00056               BYTE          v1, v2, v3;   /* local vertices */
00057        }             *tri;         /* local triangles */
00058        short         solemat;      /* sole material */
00059        int16         *trimat;      /* or local material indices */
00060        struct PJoin1 {
00061               int32         v1j;          /* non-local vertex */
00062               int16         mat;          /* material index */
00063               BYTE          v2, v3;              /* local vertices */
00064        }             *j1tri;              /* joiner triangles */
00065        struct PJoin2 {
00066               int32         v1j, v2j;     /* non-local vertices */
00067               int16         mat;          /* material index */
00068               BYTE          v3;           /* local vertex */
00069        }             *j2tri;              /* double joiner triangles */
00070        short         nverts;              /* vertex count */
00071        short         ntris;        /* local triangle count */
00072        short         nj1tris;      /* joiner triangle count */
00073        short         nj2tris;      /* double joiner triangle count */
00074 } MESHPATCH;
00075 
00076 /* A loaded mesh */
00077 typedef struct mesh {
00078        char          *name;        /* mesh file name */
00079        int           nref;         /* reference count */
00080        int           ldflags;      /* what we've loaded */
00081        CUBE          mcube;        /* bounds and octree */
00082        RREAL         uvlim[2][2];  /* local coordinate extrema */
00083        OBJECT        mat0;         /* base material index */
00084        OBJECT        nmats;        /* number of materials */
00085        MESHPATCH     *patch;              /* allocated mesh patch array */
00086        int           npatches;     /* number of mesh patches */
00087        OBJREC        *pseudo;      /* mesh pseudo objects */
00088        LUTAB         lut;          /* vertex lookup table */
00089        struct mesh   *next;        /* next mesh in list */
00090 } MESH;
00091 
00092 /* A mesh instance */
00093 typedef struct {
00094        FULLXF        x;            /* forward and backward transforms */
00095        MESH          *msh;         /* mesh object reference */
00096 } MESHINST;
00097 
00098                             /* vertex flags */
00099 #define       MT_V          01
00100 #define MT_N         02
00101 #define MT_UV        04
00102 #define MT_ALL              07
00103 
00104 /* A mesh vertex */
00105 typedef struct {
00106        int           fl;           /* setting flags */
00107        FVECT         v;            /* vertex location */
00108        FVECT         n;            /* vertex normal */
00109        RREAL         uv[2];        /* local coordinates */
00110 } MESHVERT;
00111 
00112                             /* mesh format identifier */
00113 #define MESHFMT             "Radiance_tmesh"
00114                             /* magic number for mesh files */
00115 #define MESHMAGIC    ( 1 *MAXOBJSIZ+311)  /* increment first value */
00116 
00117 
00118 extern MESH   *getmesh(char *mname, int flags);
00119 extern MESHINST      *getmeshinst(OBJREC *o, int flags);
00120 extern int    getmeshtrivid(int32 tvid[3], OBJECT *mo,
00121                             MESH *mp, OBJECT ti);
00122 extern int    getmeshvert(MESHVERT *vp, MESH *mp, int32 vid, int what);
00123 extern int    getmeshtri(MESHVERT tv[3], OBJECT *mo,
00124                             MESH *mp, OBJECT ti, int what);
00125 extern OBJREC *getmeshpseudo(MESH *mp, OBJECT mo);
00126 extern int32  addmeshvert(MESH *mp, MESHVERT *vp);
00127 extern OBJECT addmeshtri(MESH *mp, MESHVERT tv[3], OBJECT mo);
00128 extern char   *checkmesh(MESH *mp);
00129 extern void   printmeshstats(MESH *ms, FILE *fp);
00130 extern void   freemesh(MESH *ms);
00131 extern void   freemeshinst(OBJREC *o);
00132 extern void   readmesh(MESH *mp, char *path, int flags);
00133 extern void   writemesh(MESH *mp, FILE *fp);
00134 
00135 
00136 #ifdef __cplusplus
00137 }
00138 #endif
00139 #endif /* _RAD_MESH_H_ */