]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.h
common: Move infostring functions to new com_infostring.c
[xonotic/darkplaces.git] / model_brush.h
index fdc69165e7ec50614a0c04f36a331799318ad88f..bec06c30e43e73e6bac9aba7dca49ee00aa0746c 100644 (file)
@@ -21,6 +21,10 @@ 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"
+
 /*
 ==============================================================================
 
@@ -30,258 +34,185 @@ BRUSH MODELS
 */
 
 
+
 //
 // in memory representation
 //
-typedef struct
+typedef struct mvertex_s
 {
-       vec3_t          position;
+       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);
+       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;
 
-typedef struct texture_s
-{
-       // name
-       char name[16];
-       // size
-       unsigned int width, height;
-       // SURF_ flags
-       unsigned int flags;
-
-       // base texture without fullbrights, never NULL
-       rtexture_t *texture;
-       // fullbrights texture, NULL if no fullbrights used
-       rtexture_t *glowtexture;
-       // alpha texture (used for fogging), NULL if opaque
-       rtexture_t *fogtexture;
-       // detail texture (usually not used if transparent)
-       rtexture_t *detailtexture;
-
-       // total frames in sequence and alternate sequence
-       int anim_total[2];
-       // direct pointers to each of the frames in the sequences
-       // (indexed as [alternate][frame])
-       struct texture_s *anim_frames[2][10];
-       // set if animated or there is an alternate frame set
-       // (this is an optimization in the renderer)
-       int animated;
-}
-texture_t;
-
-
-#define        SURF_PLANEBACK          2
-#define        SURF_DRAWSKY            4
-#define SURF_DRAWTURB          0x10
-#define SURF_LIGHTMAP          0x20
-#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;
-
-typedef struct surfvertex_s
-{
-       // position
-       float v[3];
-       // offset into lightmap (used by vertex lighting)
-       int lightmapoffset;
-       // texture coordinates
-       float st[2];
-       // lightmap coordinates
-       float uv[2];
-       // detail texture coordinates
-       float ab[2];
-}
-surfvertex_t;
-
-// LordHavoc: replaces glpoly, triangle mesh
-typedef struct surfmesh_s
-{
-       // can be multiple meshs per surface
-       struct surfmesh_s *chain;
-       int numverts;
-       int numtriangles;
-       surfvertex_t *vertex;
-       int *index;
-}
-surfmesh_t;
-
-typedef struct msurface_s
-{
-       // should be drawn if visframe == r_framecount (set by WorldNode functions)
-       int                     visframe;
-
-       // the node plane this is on, backwards if SURF_PLANEBACK flag set
-       mplane_t        *plane;
-       // SURF_ flags
-       int                     flags;
-       struct Cshader_s        *shader;
-       struct msurface_s       *chain; // shader rendering chain
-
-       // look up in model->surfedges[], negative numbers are backwards edges
-       int                     firstedge;
-       int                     numedges;
-
-       short           texturemins[2];
-       short           extents[2];
-
-       mtexinfo_t      *texinfo;
-       texture_t       *currenttexture; // updated (animated) during early surface processing each frame
-
-       // index into d_lightstylevalue array, 255 means not used (black)
-       qbyte           styles[MAXLIGHTMAPS];
-       // RGB lighting data [numstyles][height][width][3]
-       qbyte           *samples;
-       // stain to apply on lightmap (soot/dirt/blood/whatever)
-       qbyte           *stainsamples;
-
-       // these fields are generated during model loading
-       // the lightmap texture fragment to use on the surface
-       rtexture_t *lightmaptexture;
-       // the stride when building lightmaps to comply with fragment update
-       int                     lightmaptexturestride;
-       // mesh for rendering
-       surfmesh_t      *mesh;
-
-       // these are just 3D points defining the outline of the polygon,
-       // no texcoord info (that can be generated from these)
-       int                     poly_numverts;
-       float           *poly_verts;
-       // the center is useful for sorting
-       float           poly_center[3];
-
-       // these are regenerated every frame
-       // lighting info
-       int                     dlightframe;
-       int                     dlightbits[8];
-       // avoid redundent addition of dlights
-       int                     lightframe;
-       // only render each surface once
-       int                     worldnodeframe;
-       // marked when surface is prepared for the frame
-       int                     insertframe;
-
-       // these cause lightmap updates if regenerated
-       // values currently used in lightmap
-       unsigned short cached_light[MAXLIGHTMAPS];
-       // if lightmap was lit by dynamic lights, force update on next frame
-       short           cached_dlight;
-       // to cause lightmap to be rerendered when v_overbrightbits changes
-       short           cached_lightscalebit;
-       // rerender lightmaps when r_ambient changes
-       float           cached_ambient;
-}
-msurface_t;
-
 #define SHADERSTAGE_SKY 0
 #define SHADERSTAGE_NORMAL 1
 #define SHADERSTAGE_COUNT 2
 
-struct entity_render_s;
-// change this stuff when real shaders are added
-typedef struct Cshader_s
+//#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
 {
-       void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const msurface_t *firstsurf);
-       // list of surfaces using this shader (used during surface rendering)
-       msurface_t *chain;
+       unsigned int v[2];
 }
-Cshader_t;
+medge_t;
 
-extern Cshader_t Cshader_wall_vertex;
-extern Cshader_t Cshader_wall_lightmap;
-extern Cshader_t Cshader_wall_fullbright;
-extern Cshader_t Cshader_water;
-extern Cshader_t Cshader_sky;
+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;
-       struct mportal_s        *portals;
-
+       //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;
+       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];
+       // this part unique to node
+       struct mnode_s *children[2];
 
-       unsigned short          firstsurface;
-       unsigned short          numsurfaces;
+       // 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;
-       struct mportal_s        *portals;
-
+       //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;
-
-// 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
-
-       // LordHavoc: leaf based dynamic lighting
-       int                                     dlightbits[8];
-       int                                     dlightframe;
-
-       qbyte                           *compressed_vis;
-
-       msurface_t                      **firstmarksurface;
-       int                                     nummarksurfaces;
-       qbyte                           ambient_sound_level[NUM_AMBIENTS];
+       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;
 
-typedef struct
+typedef struct mclipnode_s
+{
+       int                     planenum;
+       int                     children[2];    // negative numbers are contents
+} mclipnode_t;
+
+typedef struct hull_s
 {
-       dclipnode_t     *clipnodes;
-       mplane_t        *planes;
-       int                     firstclipnode;
-       int                     lastclipnode;
-       vec3_t          clip_mins;
-       vec3_t          clip_maxs;
-       vec3_t          clip_size;
+       mclipnode_t *clipnodes;
+       mplane_t *planes;
+       int firstclipnode;
+       int lastclipnode;
+       vec3_t clip_mins;
+       vec3_t clip_maxs;
+       vec3_t clip_size;
 }
 hull_t;
 
@@ -290,34 +221,145 @@ 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;
 
-typedef struct mlight_s
+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
 {
-       vec3_t origin;
-       float falloff;
-       vec3_t light;
-       float subtract;
-       vec3_t spotdir;
-       float spotcone; // cosine of spotlight cone angle (or 0 if not a spotlight)
-       float distbias;
        int style;
-       int numleafs; // used only for loading calculations, number of leafs this shines on
+       int value;
+       int numsurfaces;
+       int *surfacelist;
 }
-mlight_t;
+model_brush_lightstyleinfo_t;
 
-extern rtexture_t *r_notexture;
-extern texture_t r_notexture_mip;
+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;
 
-struct model_s;
-void Mod_LoadBrushModel (struct model_s *mod, void *buffer);
-void Mod_BrushInit(void);
-void Mod_FindNonSolidLocation(vec3_t pos, struct model_s *mod);
+// 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)
 
 #endif
-