#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;
for (k = 0;k < surface->num_triangles;k++)
{
tri = (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle) + k * 3;
- VectorCopy(((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + tri[0] * 3), vert[0]);
- VectorCopy(((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + tri[1] * 3), vert[1]);
- VectorCopy(((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + tri[2] * 3), vert[2]);
+ VectorCopy((surface->groupmesh->data_vertex3f + tri[0] * 3), vert[0]);
+ VectorCopy((surface->groupmesh->data_vertex3f + tri[1] * 3), vert[1]);
+ VectorCopy((surface->groupmesh->data_vertex3f + tri[2] * 3), vert[2]);
VectorSubtract(vert[1], vert[0], edge[0]);
VectorSubtract(vert[2], vert[1], edge[1]);
CrossProduct(edge[1], edge[0], facenormal);
#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;
tx->width = 16;
tx->height = 16;
tx->skin.base = r_texture_notexture;
+ tx->basematerialflags = 0;
if (i == loadmodel->brush.num_textures - 1)
{
tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES;
tx->basematerialflags |= MATERIALFLAG_WALL;
tx->supercontents = SUPERCONTENTS_SOLID;
}
- tx->basematerialflags = 0;
tx->currentframe = tx;
}
for (i = 0;i < surface->num_triangles;i++)
{
- (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 0] = 0;
- (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 1] = i + 1;
- (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 2] = i + 2;
+ (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 0] = 0 + surface->num_firstvertex;
+ (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 1] = i + 1 + surface->num_firstvertex;
+ (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)[i * 3 + 2] = i + 2 + surface->num_firstvertex;
}
// compile additional data about the surface geometry
- Mod_BuildTextureVectorsAndNormals(surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_texcoordtexture2f + 2 * surface->num_firstvertex), (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), (surface->groupmesh->data_svector3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_tvector3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_normal3f + 3 * surface->num_firstvertex));
+ Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, surface->groupmesh->data_vertex3f, surface->groupmesh->data_texcoordtexture2f, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f);
BoxFromPoints(surface->mins, surface->maxs, surface->num_vertices, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex));
// generate surface extents information
Con_Print("Mod_Q1BSP_RecursiveNodePortals: WARNING: new portal has too many points\n");
nodeportal->numpoints = 0;
}
- else
- {
- AddPortalToNodes(nodeportal, front, back);
- // split the portals of this node along this node's plane and assign them to the children of this node
- // (migrating the portals downward through the tree)
- for (portal = (portal_t *)node->portals;portal;portal = nextportal)
- {
- if (portal->nodes[0] == portal->nodes[1])
- Host_Error("Mod_Q1BSP_RecursiveNodePortals: portal has same node on both sides(2)");
- if (portal->nodes[0] == node)
- side = 0;
- else if (portal->nodes[1] == node)
- side = 1;
- else
- Host_Error("Mod_Q1BSP_RecursiveNodePortals: mislinked portal");
- nextportal = portal->next[side];
+ AddPortalToNodes(nodeportal, front, back);
- other_node = portal->nodes[!side];
- RemovePortalFromNodes(portal);
+ // split the portals of this node along this node's plane and assign them to the children of this node
+ // (migrating the portals downward through the tree)
+ for (portal = (portal_t *)node->portals;portal;portal = nextportal)
+ {
+ if (portal->nodes[0] == portal->nodes[1])
+ Host_Error("Mod_Q1BSP_RecursiveNodePortals: portal has same node on both sides(2)");
+ if (portal->nodes[0] == node)
+ side = 0;
+ else if (portal->nodes[1] == node)
+ side = 1;
+ else
+ Host_Error("Mod_Q1BSP_RecursiveNodePortals: mislinked portal");
+ nextportal = portal->next[side];
+ if (!portal->numpoints)
+ continue;
- // cut the portal into two portals, one on each side of the node plane
- PolygonD_Divide(portal->numpoints, portal->points, plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, 1.0/32.0, MAX_PORTALPOINTS, frontpoints, &numfrontpoints, MAX_PORTALPOINTS, backpoints, &numbackpoints);
+ other_node = portal->nodes[!side];
+ RemovePortalFromNodes(portal);
- if (!numfrontpoints)
- {
- if (side == 0)
- AddPortalToNodes(portal, back, other_node);
- else
- AddPortalToNodes(portal, other_node, back);
- continue;
- }
- if (!numbackpoints)
- {
- if (side == 0)
- AddPortalToNodes(portal, front, other_node);
- else
- AddPortalToNodes(portal, other_node, front);
- continue;
- }
-
- // the portal is split
- splitportal = AllocPortal();
- temp = splitportal->chain;
- *splitportal = *portal;
- splitportal->chain = temp;
- for (i = 0;i < numbackpoints*3;i++)
- splitportal->points[i] = backpoints[i];
- splitportal->numpoints = numbackpoints;
- for (i = 0;i < numfrontpoints*3;i++)
- portal->points[i] = frontpoints[i];
- portal->numpoints = numfrontpoints;
+ // cut the portal into two portals, one on each side of the node plane
+ PolygonD_Divide(portal->numpoints, portal->points, plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, 1.0/32.0, MAX_PORTALPOINTS, frontpoints, &numfrontpoints, MAX_PORTALPOINTS, backpoints, &numbackpoints);
+ if (!numfrontpoints)
+ {
+ if (side == 0)
+ AddPortalToNodes(portal, back, other_node);
+ else
+ AddPortalToNodes(portal, other_node, back);
+ continue;
+ }
+ if (!numbackpoints)
+ {
if (side == 0)
- {
AddPortalToNodes(portal, front, other_node);
- AddPortalToNodes(splitportal, back, other_node);
- }
else
- {
AddPortalToNodes(portal, other_node, front);
- AddPortalToNodes(splitportal, other_node, back);
- }
+ continue;
+ }
+
+ // the portal is split
+ splitportal = AllocPortal();
+ temp = splitportal->chain;
+ *splitportal = *portal;
+ splitportal->chain = temp;
+ for (i = 0;i < numbackpoints*3;i++)
+ splitportal->points[i] = backpoints[i];
+ splitportal->numpoints = numbackpoints;
+ for (i = 0;i < numfrontpoints*3;i++)
+ portal->points[i] = frontpoints[i];
+ portal->numpoints = numfrontpoints;
+
+ if (side == 0)
+ {
+ AddPortalToNodes(portal, front, other_node);
+ AddPortalToNodes(splitportal, back, other_node);
+ }
+ else
+ {
+ AddPortalToNodes(portal, other_node, front);
+ AddPortalToNodes(splitportal, other_node, back);
}
}
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);
}
loadmodel->brush.shadowmesh = Mod_ShadowMesh_Begin(loadmodel->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, false, true);
for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++)
- Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), NULL, NULL, NULL, NULL, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, surface->groupmesh->data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
loadmodel->brush.shadowmesh = Mod_ShadowMesh_Finish(loadmodel->mempool, loadmodel->brush.shadowmesh, false, true);
Mod_BuildTriangleNeighbors(loadmodel->brush.shadowmesh->neighbor3i, loadmodel->brush.shadowmesh->element3i, loadmodel->brush.shadowmesh->numtriangles);
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;
}
(out->groupmesh->data_lightmapcolor4f + 4 * out->num_firstvertex)[j * 4 + 3] = loadmodel->brushq3.data_color4f[(firstvertex + j) * 4 + 3];
}
for (j = 0;j < out->num_triangles*3;j++)
- (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] = loadmodel->brushq3.data_element3i[firstelement + j];
+ (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] = loadmodel->brushq3.data_element3i[firstelement + j] + out->num_firstvertex;
break;
case Q3FACETYPE_PATCH:
patchsize[0] = LittleLong(in->specific.patch.patchsize[0]);
Q3PatchTesselateFloat(2, sizeof(float[2]), (out->groupmesh->data_texcoordtexture2f + 2 * out->num_firstvertex), patchsize[0], patchsize[1], sizeof(float[2]), originaltexcoordtexture2f, xtess, ytess);
Q3PatchTesselateFloat(2, sizeof(float[2]), (out->groupmesh->data_texcoordlightmap2f + 2 * out->num_firstvertex), patchsize[0], patchsize[1], sizeof(float[2]), originaltexcoordlightmap2f, xtess, ytess);
Q3PatchTesselateFloat(4, sizeof(float[4]), (out->groupmesh->data_lightmapcolor4f + 4 * out->num_firstvertex), patchsize[0], patchsize[1], sizeof(float[4]), originalcolor4f, xtess, ytess);
- Q3PatchTriangleElements((out->groupmesh->data_element3i + 3 * out->num_firsttriangle), finalwidth, finalheight);
- out->num_triangles = Mod_RemoveDegenerateTriangles(out->num_triangles, (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), (out->groupmesh->data_vertex3f + 3 * out->num_firstvertex));
+ Q3PatchTriangleElements((out->groupmesh->data_element3i + 3 * out->num_firsttriangle), finalwidth, finalheight, out->num_firstvertex);
+ out->num_triangles = Mod_RemoveDegenerateTriangles(out->num_triangles, (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), out->groupmesh->data_vertex3f);
if (developer.integer >= 2)
{
if (out->num_triangles < finaltriangles)
out->num_collisionvertices = finalvertices;
out->num_collisiontriangles = finaltriangles;
Q3PatchTesselateFloat(3, sizeof(float[3]), out->data_collisionvertex3f, patchsize[0], patchsize[1], sizeof(float[3]), originalvertex3f, xtess, ytess);
- Q3PatchTriangleElements(out->data_collisionelement3i, finalwidth, finalheight);
+ Q3PatchTriangleElements(out->data_collisionelement3i, finalwidth, finalheight, 0);
//Mod_SnapVertices(3, out->num_vertices, (out->groupmesh->data_vertex3f + 3 * out->num_firstvertex), 0.25);
Mod_SnapVertices(3, out->num_collisionvertices, out->data_collisionvertex3f, 1);
meshvertices += out->num_vertices;
meshtriangles += out->num_triangles;
for (j = 0, invalidelements = 0;j < out->num_triangles * 3;j++)
- if ((out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] < 0 || (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] >= out->num_vertices)
+ if ((out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] < out->num_firstvertex || (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] >= out->num_firstvertex + out->num_vertices)
invalidelements++;
if (invalidelements)
{
Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, type, out->texture->name, out->texture->surfaceflags, firstvertex, out->num_vertices, firstelement, out->num_triangles * 3);
for (j = 0;j < out->num_triangles * 3;j++)
{
- Con_Printf(" %i", (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j]);
- if ((out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] < 0 || (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] >= out->num_vertices)
- (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] = 0;
+ Con_Printf(" %i", (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] - out->num_firstvertex);
+ if ((out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] < out->num_firstvertex || (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] >= out->num_firstvertex + out->num_vertices)
+ (out->groupmesh->data_element3i + 3 * out->num_firsttriangle)[j] = out->num_firstvertex;
}
Con_Print("\n");
}
// for per pixel lighting
- Mod_BuildTextureVectorsAndNormals(out->num_vertices, out->num_triangles, (out->groupmesh->data_vertex3f + 3 * out->num_firstvertex), (out->groupmesh->data_texcoordtexture2f + 2 * out->num_firstvertex), (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), (out->groupmesh->data_svector3f + 3 * out->num_firstvertex), (out->groupmesh->data_tvector3f + 3 * out->num_firstvertex), (out->groupmesh->data_normal3f + 3 * out->num_firstvertex));
+ Mod_BuildTextureVectorsAndNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, out->groupmesh->data_vertex3f, out->groupmesh->data_texcoordtexture2f, (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), out->groupmesh->data_svector3f, out->groupmesh->data_tvector3f, out->groupmesh->data_normal3f);
// calculate a bounding box
VectorClear(out->mins);
VectorClear(out->maxs);
supercontents |= SUPERCONTENTS_CORPSE;
if (nativecontents & CONTENTSQ3_NODROP)
supercontents |= SUPERCONTENTS_NODROP;
+ if (nativecontents & CONTENTSQ3_PLAYERCLIP)
+ supercontents |= SUPERCONTENTS_PLAYERCLIP;
+ if (nativecontents & CONTENTSQ3_MONSTERCLIP)
+ supercontents |= SUPERCONTENTS_MONSTERCLIP;
+ if (nativecontents & CONTENTSQ3_DONOTENTER)
+ supercontents |= SUPERCONTENTS_DONOTENTER;
return supercontents;
}
nativecontents |= CONTENTSQ3_CORPSE;
if (supercontents & SUPERCONTENTS_NODROP)
nativecontents |= CONTENTSQ3_NODROP;
+ if (supercontents & SUPERCONTENTS_PLAYERCLIP)
+ nativecontents |= CONTENTSQ3_PLAYERCLIP;
+ if (supercontents & SUPERCONTENTS_MONSTERCLIP)
+ nativecontents |= CONTENTSQ3_MONSTERCLIP;
+ if (supercontents & SUPERCONTENTS_DONOTENTER)
+ nativecontents |= CONTENTSQ3_DONOTENTER;
return nativecontents;
}
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++)
}
loadmodel->brush.shadowmesh = Mod_ShadowMesh_Begin(loadmodel->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, false, true);
for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++)
- Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), NULL, NULL, NULL, NULL, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, surface->groupmesh->data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
loadmodel->brush.shadowmesh = Mod_ShadowMesh_Finish(loadmodel->mempool, loadmodel->brush.shadowmesh, false, true);
Mod_BuildTriangleNeighbors(loadmodel->brush.shadowmesh->neighbor3i, loadmodel->brush.shadowmesh->element3i, loadmodel->brush.shadowmesh->numtriangles);
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;