X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=model_brush.h;h=bec06c30e43e73e6bac9aba7dca49ee00aa0746c;hb=fbddb742e3f36efc25a5e701b2e29e14d24e5d75;hp=41d42c956eb0a970ccc36a85982138e73d2ae8ff;hpb=8468ffaf8162a4fe8361127385c40141c375661d;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.h b/model_brush.h index 41d42c95..bec06c30 100644 --- a/model_brush.h +++ b/model_brush.h @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,6 +18,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef MODEL_BRUSH_H +#define MODEL_BRUSH_H + +#include "qtypes.h" +#include "qdefs.h" +#include "bspfile.h" + /* ============================================================================== @@ -27,192 +34,332 @@ BRUSH MODELS */ + // // in memory representation // -typedef struct +typedef struct mvertex_s { - vec3_t position; -} mvertex_t; + vec3_t position; +} +mvertex_t; -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 // plane_t structure typedef struct mplane_s { - vec3_t normal; - float dist; - int type; // for texture axis selection and fast side tests - // LordHavoc: faster than id's signbits system - int (*BoxOnPlaneSideFunc) (vec3_t emins, vec3_t emaxs, struct mplane_s *p); -} mplane_t; - -typedef struct texture_s -{ - char name[16]; - unsigned width, height; - rtexture_t *texture; - rtexture_t *glowtexture; // LordHavoc: fullbrights on walls - int anim_total; // total frames in sequence (0 = not animated) - struct texture_s *anim_frames[10]; // LordHavoc: direct pointers to each of the frames in the sequence - struct texture_s *alternate_anims; // bmodels in frame 1 use these - int transparent; // LordHavoc: transparent texture support -} texture_t; - - -#define SURF_PLANEBACK 2 -#define SURF_DRAWSKY 4 -#define SURF_DRAWSPRITE 8 -#define SURF_DRAWTURB 0x10 -#define SURF_DRAWTILED 0x20 -#define SURF_DRAWBACKGROUND 0x40 -//#define SURF_UNDERWATER 0x80 -#define SURF_DRAWNOALPHA 0x100 -#define SURF_DRAWFULLBRIGHT 0x200 -#define SURF_LIGHTBOTHSIDES 0x400 -#define SURF_CLIPSOLID 0x800 // this polygon can obscure other polygons - -typedef struct -{ - unsigned short v[2]; -} medge_t; - -typedef struct -{ - float vecs[2][4]; - texture_t *texture; - int flags; -} mtexinfo_t; - -// LordHavoc: was 7, I added one more for raw lightmap position -// (xyz st uv l) -#define VERTEXSIZE 8 - -typedef struct glpoly_s -{ - struct glpoly_s *next; - int numverts; - float verts[4][VERTEXSIZE]; // variable sized -} glpoly_t; - -typedef struct glpolysizeof_s -{ - struct glpoly_s *next; - int numverts; - int flags; // for SURF_UNDERWATER -} glpolysizeof_t; - -typedef struct msurface_s + union + { + struct + { + vec3_t normal; + vec_t dist; + }; + vec4_t normal_and_dist; + }; + // for texture axis selection and fast side tests + int type; // set by PlaneClassify() + int signbits; // set by PlaneClassify() +} +mplane_t; + +#define SHADERSTAGE_SKY 0 +#define SHADERSTAGE_NORMAL 1 +#define SHADERSTAGE_COUNT 2 + +//#define SURF_PLANEBACK 2 + +// indicates that all triangles of the surface should be added to the BIH collision system +#define MATERIALFLAG_MESHCOLLISIONS 0x00000001 +// use alpha blend on this material +#define MATERIALFLAG_ALPHA 0x00000002 +// use additive blend on this material +#define MATERIALFLAG_ADD 0x00000004 +// turn off depth test on this material +#define MATERIALFLAG_NODEPTHTEST 0x00000008 +// multiply alpha by r_wateralpha cvar +#define MATERIALFLAG_WATERALPHA 0x00000010 +// draw with no lighting +#define MATERIALFLAG_FULLBRIGHT 0x00000020 +// drawn as a normal surface (alternative to SKY) +#define MATERIALFLAG_WALL 0x00000040 +// this surface shows the sky in its place, alternative to WALL +// skipped if transparent +#define MATERIALFLAG_SKY 0x00000080 +// swirling water effect (used with MATERIALFLAG_WALL) +#define MATERIALFLAG_WATERSCROLL 0x00000100 +// skips drawing the surface +#define MATERIALFLAG_NODRAW 0x00000200 +// probably used only on q1bsp water +#define MATERIALFLAG_LIGHTBOTHSIDES 0x00000400 +// use alpha test on this material +#define MATERIALFLAG_ALPHATEST 0x00000800 +// treat this material as a blended transparency (as opposed to an alpha test +// transparency), this causes special fog behavior, and disables glDepthMask +#define MATERIALFLAG_BLENDED 0x00001000 +// render using a custom blendfunc +#define MATERIALFLAG_CUSTOMBLEND 0x00002000 +// do not cast shadows from this material +#define MATERIALFLAG_NOSHADOW 0x00004000 +// render using vertex alpha (q3bsp) as texture blend parameter between foreground (normal) skinframe and background skinframe +#define MATERIALFLAG_VERTEXTEXTUREBLEND 0x00008000 +// disables GL_CULL_FACE on this texture (making it double sided) +#define MATERIALFLAG_NOCULLFACE 0x00010000 +// render with a very short depth range (like 10% of normal), this causes entities to appear infront of most of the scene +#define MATERIALFLAG_SHORTDEPTHRANGE 0x00020000 +// render water, comprising refraction and reflection (note: this is always opaque, the shader does the alpha effect) +#define MATERIALFLAG_WATERSHADER 0x00040000 +// render refraction (note: this is just a way to distort the background, otherwise useless) +#define MATERIALFLAG_REFRACTION 0x00080000 +// render reflection +#define MATERIALFLAG_REFLECTION 0x00100000 +// use model lighting on this material (q1bsp lightmap sampling or q3bsp lightgrid, implies FULLBRIGHT is false) +#define MATERIALFLAG_MODELLIGHT 0x00200000 +// causes RSurf_GetCurrentTexture to leave alone certain fields +#define MATERIALFLAG_CUSTOMSURFACE 0x00800000 +// causes MATERIALFLAG_BLENDED to render a depth pass before rendering, hiding backfaces and other hidden geometry +#define MATERIALFLAG_TRANSDEPTH 0x01000000 +// like refraction, but doesn't distort etc. +#define MATERIALFLAG_CAMERA 0x02000000 +// disable rtlight on surface - does not disable other types of lighting (LIGHTMAP, MODELLIGHT) +#define MATERIALFLAG_NORTLIGHT 0x04000000 +// alphagen vertex - should always be used with MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW (or MATERIALFLAG_ADD instead of MATERIALFLAG_ALPHA) +#define MATERIALFLAG_ALPHAGEN_VERTEX 0x08000000 +// use occlusion buffer for corona +#define MATERIALFLAG_OCCLUDE 0x10000000 +// use vertex color instead of lighting (e.g. particles and other glowy stuff), use with MATERIALFLAG_FULLBRIGHT +#define MATERIALFLAG_VERTEXCOLOR 0x20000000 +// sample the q3bsp lightgrid in the shader rather than relying on MATERIALFLAG_MODELLIGHT +#define MATERIALFLAG_LIGHTGRID 0x40000000 +// combined mask of all attributes that require depth sorted rendering +#define MATERIALFLAGMASK_DEPTHSORTED (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST) +// combined mask of all attributes that cause some sort of transparency +#define MATERIALFLAGMASK_TRANSLUCENT (MATERIALFLAG_WATERALPHA | MATERIALFLAG_SKY | MATERIALFLAG_NODRAW | MATERIALFLAG_ALPHATEST | MATERIALFLAG_BLENDED | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION) + +typedef struct medge_s { - int visframe; // should be drawn when node is crossed - - mplane_t *plane; - int flags; - - int firstedge; // look up in model->surfedges[], negative numbers - int numedges; // are backwards edges - - short texturemins[2]; - short extents[2]; - - short light_s, light_t; // gl lightmap coordinates - - glpoly_t *polys; // multiple if warped - - mtexinfo_t *texinfo; - -// lighting info - int dlightframe; - int dlightbits[8]; - - int lightframe; // avoid redundent addition of dlights - int worldnodeframe; // only render each surface once + unsigned int v[2]; +} +medge_t; - int lightmaptexturenum; - byte styles[MAXLIGHTMAPS]; - unsigned short cached_light[MAXLIGHTMAPS]; // values currently used in lightmap - short cached_dlight; // LordHavoc: if lightmap was lit by dynamic lights, update on frame after end of effect to erase it - short cached_lighthalf; // LordHavoc: to cause lightmap to be rerendered when lighthalf changes - float cached_ambient; // LordHavoc: rerender lightmaps when r_ambient changes - byte *samples; // [numstyles*surfsize] -} msurface_t; +struct entity_render_s; +struct texture_s; +struct msurface_s; -// warning: if this is changed, references must be updated in cpu_* assembly files typedef struct mnode_s { -// common with leaf - int contents; // 0, to differentiate from leafs - - struct mnode_s *parent; + //this part shared between node and leaf + mplane_t *plane; // != NULL + struct mnode_s *parent; struct mportal_s *portals; + // for bounding box culling + vec3_t mins; + vec3_t maxs; + // supercontents from all brushes inside this node or leaf + int combinedsupercontents; -// node specific - mplane_t *plane; - struct mnode_s *children[2]; - - unsigned short firstsurface; - unsigned short numsurfaces; -} mnode_t; - + // this part unique to node + struct mnode_s *children[2]; + // q1bsp specific + unsigned int firstsurface; + unsigned int numsurfaces; +} +mnode_t; typedef struct mleaf_s { -// common with node - int contents; // will be a negative contents number - - struct mnode_s *parent; + //this part shared between node and leaf + mplane_t *plane; // == NULL + struct mnode_s *parent; struct mportal_s *portals; - -// leaf specific -// int visframe; // visible if current (r_framecount) -// int worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame - int portalmarkid; // used by polygon-through-portals visibility checker - // for bounding box culling - vec3_t mins; - vec3_t maxs; - - // LordHavoc: leaf based dynamic lighting - int dlightbits[8]; - int dlightframe; - - byte *compressed_vis; + vec3_t mins; + vec3_t maxs; + // supercontents from all brushes inside this node or leaf + int combinedsupercontents; + + // this part unique to leaf + // common + int clusterindex; // -1 is not in pvs, >= 0 is pvs bit number + int areaindex; // q3bsp + int containscollisionsurfaces; // indicates whether the leafsurfaces contains q3 patches + int numleafsurfaces; + int *firstleafsurface; + int numleafbrushes; // q3bsp + int *firstleafbrush; // q3bsp + unsigned char ambient_sound_level[NUM_AMBIENTS]; // q1bsp + int contents; // q1bsp: // TODO: remove (only used temporarily during loading when making collision hull 0) + int portalmarkid; // q1bsp // used by see-polygon-through-portals visibility checker +} +mleaf_t; - msurface_t **firstmarksurface; - int nummarksurfaces; - byte ambient_sound_level[NUM_AMBIENTS]; -} mleaf_t; +typedef struct mclipnode_s +{ + int planenum; + int children[2]; // negative numbers are contents +} mclipnode_t; -typedef struct +typedef struct hull_s { - dclipnode_t *clipnodes; - mplane_t *planes; - int firstclipnode; - int lastclipnode; - vec3_t clip_mins; - vec3_t clip_maxs; -} hull_t; + mclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; + vec3_t clip_size; +} +hull_t; typedef struct mportal_s { struct mportal_s *next; // the next portal on this leaf mleaf_t *here; // the leaf this portal is on mleaf_t *past; // the leaf through this portal (infront) - mvertex_t *points; int numpoints; + mvertex_t *points; + vec3_t mins, maxs; // culling mplane_t plane; - int visframe; // is this portal visible this frame? + double tracetime; // refreshed to realtime by traceline tests } mportal_t; -extern void CL_ParseEntityLump(char *entdata); -extern rtexture_t *r_notexture; -extern texture_t r_notexture_mip; +typedef struct svbspmesh_s +{ + struct svbspmesh_s *next; + int numverts, maxverts; + int numtriangles, maxtriangles; + float *verts; + int *elements; +} +svbspmesh_t; + +typedef struct model_brush_lightstyleinfo_s +{ + int style; + int value; + int numsurfaces; + int *surfacelist; +} +model_brush_lightstyleinfo_t; + +typedef struct model_brush_s +{ + // true if this model is a HalfLife .bsp file + qbool ishlbsp; + // true if this model is a BSP2rmqe .bsp file (expanded 32bit bsp format for rmqe) + qbool isbsp2rmqe; + // true if this model is a BSP2 .bsp file (expanded 32bit bsp format for DarkPlaces, others?) + qbool isbsp2; + // true if this model is a Quake2 .bsp file (IBSP38) + qbool isq2bsp; + // true if this model is a Quake3 .bsp file (IBSP46) + qbool isq3bsp; + // true if this model is a Quake1/Quake2 .bsp file where skymasking capability exists + qbool skymasking; + // string of entity definitions (.map format) + char *entities; + + // if not NULL this is a submodel + struct model_s *parentmodel; + // (this is the number of the submodel, an index into submodels) + int submodel; + + // number of submodels in this map (just used by server to know how many + // submodels to load) + int numsubmodels; + // pointers to each of the submodels + struct model_s **submodels; + + int num_planes; + mplane_t *data_planes; + + int num_nodes; + mnode_t *data_nodes; + + // visible leafs, not counting 0 (solid) + int num_visleafs; + // number of actual leafs (including 0 which is solid) + int num_leafs; + mleaf_t *data_leafs; + + int num_leafbrushes; + int *data_leafbrushes; + + int num_leafsurfaces; + int *data_leafsurfaces; + + int num_portals; + mportal_t *data_portals; + + int num_portalpoints; + mvertex_t *data_portalpoints; + + int num_brushes; + struct q3mbrush_s *data_brushes; + + int num_brushsides; + struct q3mbrushside_s *data_brushsides; + + // pvs + int num_pvsclusters; + int num_pvsclusterbytes; + unsigned char *data_pvsclusters; + // example + //pvschain = model->brush.data_pvsclusters + mycluster * model->brush.num_pvsclusterbytes; + //if (pvschain[thatcluster >> 3] & (1 << (thatcluster & 7))) + + // collision geometry for q3 curves + int num_collisionvertices; + int num_collisiontriangles; + float *data_collisionvertex3f; + int *data_collisionelement3i; + + // a mesh containing all shadow casting geometry for the whole model (including submodels), portions of this are referenced by each surface's num_firstshadowmeshtriangle + struct shadowmesh_s *shadowmesh; + + // a mesh containing all SUPERCONTENTS_SOLID surfaces for this model or submodel, for physics engines to use + struct shadowmesh_s *collisionmesh; + + // common functions + int (*SuperContentsFromNativeContents)(int nativecontents); + int (*NativeContentsFromSuperContents)(int supercontents); + unsigned char *(*GetPVS)(struct model_s *model, const vec3_t p); + int (*FatPVS)(struct model_s *model, const vec3_t org, vec_t radius, unsigned char *pvsbuffer, int pvsbufferlength, qbool merge); + int (*BoxTouchingPVS)(struct model_s *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs); + int (*BoxTouchingLeafPVS)(struct model_s *model, const unsigned char *pvs, const vec3_t mins, const vec3_t maxs); + int (*BoxTouchingVisibleLeafs)(struct model_s *model, const unsigned char *visibleleafs, const vec3_t mins, const vec3_t maxs); + int (*FindBoxClusters)(struct model_s *model, const vec3_t mins, const vec3_t maxs, int maxclusters, int *clusterlist); + void (*LightPoint)(struct model_s *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal); + void (*FindNonSolidLocation)(struct model_s *model, const vec3_t in, vec3_t out, vec_t radius); + mleaf_t *(*PointInLeaf)(struct model_s *model, const vec3_t p); + // these are actually only found on brushq1, but NULL is handled gracefully + void (*AmbientSoundLevelsForPoint)(struct model_s *model, const vec3_t p, unsigned char *out, int outsize); + void (*RoundUpToHullSize)(struct model_s *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs); + // trace a line of sight through this model (returns false if the line if sight is definitely blocked) + qbool (*TraceLineOfSight)(struct model_s *model, const vec3_t start, const vec3_t end, const vec3_t acceptmins, const vec3_t acceptmaxs); + + char skybox[MAX_QPATH]; + + struct skinframe_s *solidskyskinframe; + struct skinframe_s *alphaskyskinframe; + + qbool supportwateralpha; + + // QuakeWorld + int qw_md4sum; + int qw_md4sum2; +} +model_brush_t; + +// the first cast is to shut up a stupid warning by clang, the second cast is to make both sides have the same type +#define CHECKPVSBIT(pvs,b) ((b) >= 0 ? (unsigned char) ((pvs)[(b) >> 3] & (1 << ((b) & 7))) : (unsigned char) false) +#define SETPVSBIT(pvs,b) (void) ((b) >= 0 ? (unsigned char) ((pvs)[(b) >> 3] |= (1 << ((b) & 7))) : (unsigned char) false) +#define CLEARPVSBIT(pvs,b) (void) ((b) >= 0 ? (unsigned char) ((pvs)[(b) >> 3] &= ~(1 << ((b) & 7))) : (unsigned char) false) -struct model_s; -extern void Mod_LoadBrushModel (struct model_s *mod, void *buffer); -extern void Mod_BrushInit(void); +#endif