-static int Mod_Q3BSP_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs)
-{
- int clusterindex, side, nodestackindex = 0;
- q3mnode_t *node, *nodestack[1024];
- node = model->brushq3.data_nodes;
- if (!model->brush.num_pvsclusters)
- return true;
- 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 = ((q3mleaf_t *)node)->clusterindex;
-#if 0
- if (clusterindex >= model->brush.num_pvsclusters)
- {
- Con_Printf("%i >= %i\n", clusterindex, model->brush.num_pvsclusters);
- return true;
- }
-#endif
- 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;
-}
-
-//Returns PVS data for a given point
-//(note: can return NULL)
-static qbyte *Mod_Q3BSP_GetPVS(model_t *model, const vec3_t p)
-{
- q3mnode_t *node;
- Mod_CheckLoaded(model);
- node = model->brushq3.data_nodes;
- while (node->plane)
- node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p,node->plane->normal)) < node->plane->dist];
- if (((q3mleaf_t *)node)->clusterindex >= 0)
- return model->brush.data_pvsclusters + ((q3mleaf_t *)node)->clusterindex * model->brush.num_pvsclusterbytes;
- else
- return NULL;
-}
-
-static void Mod_Q3BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbytes, q3mnode_t *node)
-{
- while (node->plane)
- {
- float d = PlaneDiff(org, node->plane);
- if (d > radius)
- node = node->children[0];
- else if (d < -radius)
- node = node->children[1];
- else
- {
- // go down both sides
- Mod_Q3BSP_FatPVS_RecursiveBSPNode(model, org, radius, pvsbuffer, pvsbytes, node->children[0]);
- node = node->children[1];
- }
- }
- // if this leaf is in a cluster, accumulate the pvs bits
- if (((q3mleaf_t *)node)->clusterindex >= 0)
- {
- int i;
- qbyte *pvs = model->brush.data_pvsclusters + ((q3mleaf_t *)node)->clusterindex * model->brush.num_pvsclusterbytes;
- for (i = 0;i < pvsbytes;i++)
- pvsbuffer[i] |= pvs[i];
- }
-}
-
-//Calculates a PVS that is the inclusive or of all leafs within radius pixels
-//of the given point.
-static int Mod_Q3BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength)
-{
- int bytes = model->brush.num_pvsclusterbytes;
- bytes = min(bytes, pvsbufferlength);
- if (r_novis.integer || !model->brush.num_pvsclusters || !Mod_Q3BSP_GetPVS(model, org))
- {
- memset(pvsbuffer, 0xFF, bytes);
- return bytes;
- }
- memset(pvsbuffer, 0, bytes);
- Mod_Q3BSP_FatPVS_RecursiveBSPNode(model, org, radius, pvsbuffer, bytes, model->brushq3.data_nodes);
- return bytes;
-}
-
-