ericw-tools/include/qbsp/qbsp.hh

358 lines
10 KiB
C++

/*
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1997 Greg Lewis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
// qbsp.h
#ifndef QBSP_H
#define QBSP_H
#include <vector>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "bspfile.hh"
#include "file.hh"
#include "warnerr.hh"
#ifndef offsetof
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
#ifndef __GNUC__
#define __attribute__(x)
#endif
/*
* Clipnodes need to be stored as a 16-bit offset. Originally, this was a
* signed value and only the positive values up to 32767 were available. Since
* the negative range was unused apart from a few values reserved for flags,
* this has been extended to allow up to 65520 (0xfff0) clipnodes (with a
* suitably modified engine).
*/
#define MAX_BSP_CLIPNODES 0xfff0
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
// Various other geometry maximums
#define MAX_POINTS_ON_WINDING 96
#define MAXEDGES 64
#define MAXPOINTS 60 // don't let a base face get past this
// because it can be split more later
// For brush.c, normal and +16 (?)
#define NUM_HULLS 2
// 0-2 are axial planes
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
// planenum for a leaf (?)
#define PLANENUM_LEAF -1
// Which side of polygon a point is on
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2
#define SIDE_CROSS -2
// Pi
#define Q_PI 3.14159265358979323846
// Possible contents of a leaf node
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
#define CONTENTS_SLIME -4
#define CONTENTS_LAVA -5
#define CONTENTS_SKY -6
#define CONTENTS_CLIP -7 /* compiler internal use only */
#define CONTENTS_HINT -8 /* compiler internal use only */
#define CONTENTS_ORIGIN -9 /* compiler internal use only */
// Special contents flags for the compiler only
#define CFLAGS_DETAIL (1U << 0)
// Texture flags. Only TEX_SPECIAL is written to the .bsp.
// Extended flags are written to a .texinfo file and read by the light tool
#define TEX_SPECIAL (1ULL << 0) /* sky or liquid (no lightmap or subdivision */
#define TEX_SKIP (1ULL << 1) /* an invisible surface */
#define TEX_HINT (1ULL << 2) /* hint surface */
#define TEX_NODIRT (1ULL << 3) /* don't receive dirtmapping */
#define TEX_PHONG_ANGLE_SHIFT 4
#define TEX_PHONG_ANGLE_MASK (255ULL << TEX_PHONG_ANGLE_SHIFT) /* 8 bit value. if non zero, enables phong shading and gives the angle threshold to use. */
#define TEX_MINLIGHT_SHIFT 12
#define TEX_MINLIGHT_MASK (255ULL << TEX_MINLIGHT_SHIFT) /* 8 bit value, minlight value for this face. */
#define TEX_MINLIGHT_COLOR_R_SHIFT 20
#define TEX_MINLIGHT_COLOR_R_MASK (255ULL << TEX_MINLIGHT_COLOR_R_SHIFT) /* 8 bit value, red minlight color for this face. */
#define TEX_MINLIGHT_COLOR_G_SHIFT 28
#define TEX_MINLIGHT_COLOR_G_MASK (255ULL << TEX_MINLIGHT_COLOR_G_SHIFT) /* 8 bit value, green minlight color for this face. */
#define TEX_MINLIGHT_COLOR_B_SHIFT 36
#define TEX_MINLIGHT_COLOR_B_MASK (255ULL << TEX_MINLIGHT_COLOR_B_SHIFT) /* 8 bit value, blue minlight color for this face. */
/*
* The quality of the bsp output is highly sensitive to these epsilon values.
* Notes:
* - T-junction calculations are sensitive to errors and need the various
* epsilons to be such that EQUAL_EPSILON < T_EPSILON < CONTINUOUS_EPSILON.
* ( TODO: re-check if CONTINUOUS_EPSILON is still directly related )
*/
#define NORMAL_EPSILON 0.000001
#define ANGLEEPSILON 0.000001
#define DIST_EPSILON 0.0001
#define ZERO_EPSILON 0.0001
#define DISTEPSILON 0.0001
#define POINT_EPSILON 0.0001
#define ON_EPSILON options.on_epsilon
#define EQUAL_EPSILON 0.0001
#define T_EPSILON 0.0002
#define CONTINUOUS_EPSILON 0.0005
#define BOGUS_RANGE 65536
// the exact bounding box of the brushes is expanded some for the headnode
// volume. is this still needed?
#define SIDESPACE 24
/*
* If this enum is changed, make sure to also update MemSize and PrintMem
*/
enum {
BSP_ENT,
BSP_PLANE,
BSP_TEX,
BSP_VERTEX,
BSP_VIS,
BSP_NODE,
BSP_TEXINFO,
BSP_FACE,
BSP_LIGHT,
BSP_CLIPNODE,
BSP_LEAF,
BSP_MARKSURF,
BSP_EDGE,
BSP_SURFEDGE,
BSP_MODEL,
MAPFACE,
MAPBRUSH,
MAPENTITY,
WINDING,
FACE,
PLANE,
PORTAL,
SURFACE,
NODE,
BRUSH,
MIPTEX,
WVERT,
WEDGE,
HASHVERT,
OTHER,
GLOBAL
};
#include <common/cmdlib.hh>
#include <common/mathlib.hh>
#include <qbsp/winding.hh>
typedef struct mtexinfo_s {
float vecs[2][4]; /* [s/t][xyz offset] */
int32_t miptex;
uint64_t flags;
bool operator<(const mtexinfo_s &other) const {
if (this->miptex < other.miptex)
return true;
if (this->miptex > other.miptex)
return false;
if (this->flags < other.flags)
return true;
if (this->flags > other.flags)
return false;
for (int i=0; i<2; i++) {
for (int j=0; j<4; j++) {
if (this->vecs[i][j] < other.vecs[i][j])
return true;
if (this->vecs[i][j] > other.vecs[i][j])
return false;
}
}
return false;
}
} mtexinfo_t;
typedef struct visfacet_s {
struct visfacet_s *next;
int planenum;
int planeside; // which side is the front of the face
int texinfo;
short contents[2]; // 0 = front side
short cflags[2]; // contents flags
short lmshift[2]; //lightmap scale.
struct visfacet_s *original; // face on node
int outputnumber; // only valid for original faces after
// write surfaces
vec3_t origin;
vec_t radius;
int *edges;
winding_t w;
} face_t;
typedef struct surface_s {
struct surface_s *next;
struct surface_s *original; // before BSP cuts it up
int planenum;
int outputplanenum; // only valid after WriteSurfacePlanes
vec3_t mins, maxs;
bool onnode; // true if surface has already been used
// as a splitting node
bool detail_separator; // true if split generated by a detail brush
face_t *faces; // links to all faces on either side of the surf
bool has_detail; // 1 if the surface has detail brushes
bool has_struct; // 1 if the surface has non-detail brushes
short lmshift;
} surface_t;
// there is a node_t structure for every node and leaf in the bsp tree
typedef struct node_s {
vec3_t mins, maxs; // bounding volume, not just points inside
// information for decision nodes
int planenum; // -1 = leaf node
int outputplanenum; // only valid after WriteNodePlanes
int firstface; // decision node only
int numfaces; // decision node only
struct node_s *children[2]; // only valid for decision nodes
face_t *faces; // decision nodes only, list for both sides
// information for leafs
int contents; // leaf nodes (0 for decision nodes)
face_t **markfaces; // leaf nodes only, point to node faces
struct portal_s *portals;
int visleafnum; // -1 = solid
int viscluster; // detail cluster for faster vis
int fillmark; // for flood filling
int occupied; // entity number in leaf for outside filling
bool detail_separator; // for vis portal generation
} node_t;
#include <qbsp/brush.hh>
#include <qbsp/csg4.hh>
#include <qbsp/solidbsp.hh>
#include <qbsp/merge.hh>
#include <qbsp/surfaces.hh>
#include <qbsp/portals.hh>
#include <qbsp/region.hh>
#include <qbsp/tjunc.hh>
#include <qbsp/writebsp.hh>
#include <qbsp/outside.hh>
typedef enum {
TX_QUAKED = 0,
TX_QUARK_TYPE1 = 1,
TX_QUARK_TYPE2 = 2,
TX_VALVE_220 = 3,
TX_BRUSHPRIM = 4
} texcoord_style_t;
enum class conversion_t {
quake, quake2, valve, bp
};
typedef struct options_s {
bool fNofill;
bool fNoclip;
bool fNoskip;
bool fOnlyents;
bool fConvertMapFormat;
conversion_t convertMapFormat;
bool fVerbose;
bool fAllverbose;
bool fSplitspecial;
bool fSplitturb;
bool fSplitsky;
bool fTranswater;
bool fTranssky;
bool fOldaxis;
bool fBspleak;
bool fNoverbose;
bool fOldleak;
bool fNopercent;
bool forceGoodTree;
bool fixRotateObjTexture;
bool fbspx_brushes;
bool fNoTextures;
int hexen2;/*2 if the worldspawn mission pack flag was set*/
int BSPVersion;
int dxSubdivide;
int dxLeakDist;
int maxNodeSize;
char szMapName[512];
char szBSPName[512];
char wadPath[512];
vec_t on_epsilon;
bool fObjExport;
bool fOmitDetail;
} options_t;
extern options_t options;
#include <qbsp/map.hh>
#include <qbsp/util.hh>
int qbsp_main(int argc, const char **argv);
void ProcessEntity(mapentity_t *entity, const int hullnum);
void CreateSingleHull(const int hullnum);
void CreateHulls(void);
#endif