#include "wad.h"
-qbyte mod_q1bsp_novis[(MAX_MAP_LEAFS + 7)/ 8];
-
//cvar_t r_subdivide_size = {CVAR_SAVE, "r_subdivide_size", "128"};
cvar_t halflifebsp = {0, "halflifebsp", "0"};
cvar_t r_novis = {0, "r_novis", "0"};
cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "1"};
cvar_t mod_q3bsp_debugtracebrush = {0, "mod_q3bsp_debugtracebrush", "0"};
-static void Mod_Q1BSP_Collision_Init (void);
void Mod_BrushInit(void)
{
// Cvar_RegisterVariable(&r_subdivide_size);
Cvar_RegisterVariable(&mod_q3bsp_curves_collisions);
Cvar_RegisterVariable(&mod_q3bsp_optimizedtraceline);
Cvar_RegisterVariable(&mod_q3bsp_debugtracebrush);
- memset(mod_q1bsp_novis, 0xff, sizeof(mod_q1bsp_novis));
- Mod_Q1BSP_Collision_Init();
}
static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
return false;
}
+static int Mod_Q1BSP_BoxTouchingLeafPVS(model_t *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs)
+{
+ int clusterindex, side, nodestackindex = 0;
+ mnode_t *node, *nodestack[1024];
+ if (!model->brush.num_leafs)
+ return true;
+ node = model->brush.data_nodes;
+ for (;;)
+ {
+ if (node->plane)
+ {
+ // node - recurse down the BSP tree
+ side = BoxOnPlaneSide(mins, maxs, node->plane) - 1;
+ if (side < 2)
+ {
+ // box is on one side of plane, take that path
+ node = node->children[side];
+ }
+ else
+ {
+ // box crosses plane, take one path and remember the other
+ if (nodestackindex < 1024)
+ nodestack[nodestackindex++] = node->children[0];
+ node = node->children[1];
+ }
+ }
+ else
+ {
+ // leaf - check cluster bit
+ clusterindex = ((mleaf_t *)node) - model->brush.data_leafs;
+ if (CHECKPVSBIT(pvs, clusterindex))
+ {
+ // it is visible, return immediately with the news
+ return true;
+ }
+ else
+ {
+ // nothing to see here, try another path we didn't take earlier
+ if (nodestackindex == 0)
+ break;
+ node = nodestack[--nodestackindex];
+ }
+ }
+ }
+ // it is not visible
+ return false;
+}
+
static int Mod_Q1BSP_BoxTouchingVisibleLeafs(model_t *model, const qbyte *visibleleafs, const vec3_t mins, const vec3_t maxs)
{
int side, nodestackindex = 0;
#endif
}
-static hull_t box_hull;
-static dclipnode_t box_clipnodes[6];
-static mplane_t box_planes[6];
-
-static void Mod_Q1BSP_Collision_Init (void)
-{
- int i;
- int side;
-
- //Set up the planes and clipnodes so that the six floats of a bounding box
- //can just be stored out and get a proper hull_t structure.
-
- box_hull.clipnodes = box_clipnodes;
- box_hull.planes = box_planes;
- box_hull.firstclipnode = 0;
- box_hull.lastclipnode = 5;
-
- for (i = 0;i < 6;i++)
- {
- box_clipnodes[i].planenum = i;
-
- side = i&1;
-
- box_clipnodes[i].children[side] = CONTENTS_EMPTY;
- if (i != 5)
- box_clipnodes[i].children[side^1] = i + 1;
- else
- box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
-
- box_planes[i].type = i>>1;
- box_planes[i].normal[i>>1] = 1;
- }
-}
-
void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents)
{
#if 1
Collision_TraceLineBrushFloat(trace, start, end, &cbox, &cbox);
#else
RecursiveHullCheckTraceInfo_t rhc;
+ static hull_t box_hull;
+ static dclipnode_t box_clipnodes[6];
+ static mplane_t box_planes[6];
// fill in a default trace
memset(&rhc, 0, sizeof(rhc));
memset(trace, 0, sizeof(trace_t));
#if COLLISIONPARANOID >= 3
Con_Printf("box_planes %f:%f %f:%f %f:%f\ncbox %f %f %f:%f %f %f\nbox %f %f %f:%f %f %f\n", box_planes[0].dist, box_planes[1].dist, box_planes[2].dist, box_planes[3].dist, box_planes[4].dist, box_planes[5].dist, cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2], mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]);
#endif
+
+ if (box_hull.clipnodes == NULL)
+ {
+ int i, side;
+
+ //Set up the planes and clipnodes so that the six floats of a bounding box
+ //can just be stored out and get a proper hull_t structure.
+
+ box_hull.clipnodes = box_clipnodes;
+ box_hull.planes = box_planes;
+ box_hull.firstclipnode = 0;
+ box_hull.lastclipnode = 5;
+
+ for (i = 0;i < 6;i++)
+ {
+ box_clipnodes[i].planenum = i;
+
+ side = i&1;
+
+ box_clipnodes[i].children[side] = CONTENTS_EMPTY;
+ if (i != 5)
+ box_clipnodes[i].children[side^1] = i + 1;
+ else
+ box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
+
+ box_planes[i].type = i>>1;
+ box_planes[i].normal[i>>1] = 1;
+ }
+ }
+
// trace a line through the generated clipping hull
//rhc.boxsupercontents = boxsupercontents;
rhc.hull = &box_hull;
extern void R_Q1BSP_DrawSky(entity_render_t *ent);
extern void R_Q1BSP_Draw(entity_render_t *ent);
-extern void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
+extern void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, qbyte *outleafpvs, int *outnumleafspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
extern void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
-extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
+extern void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, const int *surfacelist);
void Mod_Q1BSP_Load(model_t *mod, void *buffer)
{
int i, j, k;
mod->brush.GetPVS = Mod_Q1BSP_GetPVS;
mod->brush.FatPVS = Mod_Q1BSP_FatPVS;
mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS;
+ mod->brush.BoxTouchingLeafPVS = Mod_Q1BSP_BoxTouchingLeafPVS;
mod->brush.BoxTouchingVisibleLeafs = Mod_Q1BSP_BoxTouchingVisibleLeafs;
mod->brush.LightPoint = Mod_Q1BSP_LightPoint;
mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint;
mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize;
- mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
+ mod->brush.PointInLeaf = Mod_Q1BSP_PointInLeaf;
if (loadmodel->isworldmodel)
Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
mod->brush.GetPVS = NULL;
mod->brush.FatPVS = NULL;
mod->brush.BoxTouchingPVS = NULL;
+ mod->brush.BoxTouchingLeafPVS = NULL;
mod->brush.BoxTouchingVisibleLeafs = NULL;
mod->brush.LightPoint = NULL;
mod->brush.AmbientSoundLevelsForPoint = NULL;
Con_Printf(" %s", parameter[j]);
Con_Print("\n");
}
- if (passnumber == 0 && numparameters >= 1)
+ if (passnumber == 0 && numparameters >= 1 && (flags & Q3SURFACEPARM_TRANS))
{
if (!strcasecmp(parameter[0], "blendfunc"))
{
strlcpy(firstpasstexturename, parameter[1], sizeof(firstpasstexturename));
else if (numparameters >= 3 && !strcasecmp(parameter[0], "animmap"))
strlcpy(firstpasstexturename, parameter[2], sizeof(firstpasstexturename));
+ else if (numparameters >= 2 && !strcasecmp(parameter[0], "alphafunc"))
+ flags2 |= Q3TEXTUREFLAG_ALPHATEST;
}
- if (!strcasecmp(parameter[0], "alphafunc"))
- flags2 |= Q3TEXTUREFLAG_ALPHATEST;
// break out a level if it was }
if (!strcasecmp(com_token, "}"))
break;
flags2 |= Q3TEXTUREFLAG_AUTOSPRITE2;
}
}
- // force transparent render path for a number of odd
- // shader effects to avoid bogging down the normal
- // render path unnecessarily
- if (flags2 & (Q3TEXTUREFLAG_ADDITIVE | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2 | Q3TEXTUREFLAG_ALPHATEST))
- flags |= Q3SURFACEPARM_TRANS;
// add shader to list (shadername and flags)
// actually here we just poke into the texture settings
for (j = 0, out = loadmodel->brush.data_textures;j < loadmodel->brush.num_textures;j++, out++)
else
out->basematerialflags |= MATERIALFLAG_WALL;
if (out->surfaceparms & Q3SURFACEPARM_TRANS)
- out->basematerialflags |= MATERIALFLAG_TRANSPARENT;
- if (out->textureflags & Q3TEXTUREFLAG_ADDITIVE)
- out->basematerialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
+ {
+ if (out->textureflags & Q3TEXTUREFLAG_ADDITIVE)
+ out->basematerialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
+ else
+ out->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
+ }
strlcpy(out->firstpasstexturename, firstpasstexturename, sizeof(out->firstpasstexturename));
if ((flags & Q3SURFACEPARM_SKY) && sky[0])
{
}
if (!Mod_LoadSkinFrame(&out->skin, out->name, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, false, true))
if (!Mod_LoadSkinFrame(&out->skin, out->firstpasstexturename, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, false, true))
- Con_Printf("%s: texture loading for shader \"%s\" failed (first layer \"%s\" not found either)\n", loadmodel->name, out->name, out->firstpasstexturename);
- if (out->skin.fog)
- out->basematerialflags |= (MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT);
+ if (cls.state != ca_dedicated)
+ Con_Printf("%s: texture loading for shader \"%s\" failed (first layer \"%s\" not found either)\n", loadmodel->name, out->name, out->firstpasstexturename);
// no animation
out->currentframe = out;
}
mod->brush.GetPVS = Mod_Q1BSP_GetPVS;
mod->brush.FatPVS = Mod_Q1BSP_FatPVS;
mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS;
+ mod->brush.BoxTouchingLeafPVS = Mod_Q1BSP_BoxTouchingLeafPVS;
mod->brush.BoxTouchingVisibleLeafs = Mod_Q1BSP_BoxTouchingVisibleLeafs;
mod->brush.LightPoint = Mod_Q3BSP_LightPoint;
mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
+ mod->brush.PointInLeaf = Mod_Q1BSP_PointInLeaf;
mod->Draw = R_Q1BSP_Draw;
mod->GetLightInfo = R_Q1BSP_GetLightInfo;
mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
Mod_Q3BSP_LoadPVS(&header->lumps[Q3LUMP_PVS]);
loadmodel->brush.numsubmodels = loadmodel->brushq3.num_models;
+ // the MakePortals code works fine on the q3bsp data as well
+ Mod_Q1BSP_MakePortals();
+
// make a single combined shadow mesh to allow optimized shadow volume creation
numshadowmeshtriangles = 0;
for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++)
mod->brush.GetPVS = NULL;
mod->brush.FatPVS = NULL;
mod->brush.BoxTouchingPVS = NULL;
+ mod->brush.BoxTouchingLeafPVS = NULL;
mod->brush.BoxTouchingVisibleLeafs = NULL;
mod->brush.LightPoint = NULL;
mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;