]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.h
Add a proper README with build instructions and links to the available chats. To...
[xonotic/darkplaces.git] / model_brush.h
index c88f1095ecdfa29729103beaf36e70c0bbf6373a..bec06c30e43e73e6bac9aba7dca49ee00aa0746c 100644 (file)
@@ -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,187 +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
-// LordHavoc: added these for lava and teleport textures
-#define SURF_DRAWNOALPHA       0x100
-#define SURF_DRAWFULLBRIGHT    0x200
-// LordHavoc: light both sides
-#define SURF_LIGHTBOTHSIDES            0x400
-
-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
-#define        VERTEXSIZE      8
-
-typedef struct glpoly_s
-{
-       struct  glpoly_s        *next;
-       struct  glpoly_s        *chain;
-       int             numverts;
-       int             flags;                  // for SURF_UNDERWATER
-       float   verts[4][VERTEXSIZE];   // variable sized (xyz s1t1 s2t2)
-} glpoly_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
-       int                     vismarkframe;   // node needs to be traversed if current (r_vismarkframecount)
-
-       // for bounding box culling
-       vec3_t          mins;
-       vec3_t          maxs;
-
-       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;               // wil be a negative contents number
-       int                     vismarkframe;   // node needs to be traversed if current (r_vismarkframecount)
-
-       // for bounding box culling
-       vec3_t          mins;
-       vec3_t          maxs;
-
-       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;
+
+       // 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;
 
-// 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
-
-       // LordHavoc: leaf based dynamic lighting
-       int                     dlightbits[8];
-       int                     dlightframe;
-
-       byte            *compressed_vis;
-//     efrag_t         *efrags;
-
-       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;
+       double tracetime; // refreshed to realtime by traceline tests
 }
 mportal_t;
 
-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)
+
+#endif